Exemple #1
0
        /**
         * Constructor.
         *
         * @param fontDictionary the corresponding dictionary
         * @throws IOException it something went wrong
         */
        public PdfType1CFont(PdfDirectObject fontDictionary)
            : base(fontDictionary)
        {
            FontDescriptor fd = FontDescriptor;

            byte[] bytes = null;
            if (fd != null)
            {
                var ff3Stream = fd.FontFile3;
                if (ff3Stream != null)
                {
                    bytes = ff3Stream.BaseDataObject.ExtractBody(true).GetBuffer();
                    if (bytes.Length == 0)
                    {
                        Debug.WriteLine($"error: Invalid data for embedded Type1C font {Name}");
                        bytes = null;
                    }
                }
            }

            bool         fontIsDamaged = false;
            CFFType1Font cffEmbedded   = null;

            try
            {
                if (bytes != null)
                {
                    // note: this could be an OpenType file, fortunately CFFParser can handle that
                    CFFParser cffParser = new CFFParser();
                    cffEmbedded = (CFFType1Font)cffParser.Parse(bytes, new FF3ByteSource(fd, bytes))[0];
                }
            }
            catch (Exception e)
            {
                Debug.WriteLine($"error: Can't read the embedded Type1C font {Name} {e}");
                fontIsDamaged = true;
            }
            isDamaged = fontIsDamaged;
            cffFont   = cffEmbedded;

            if (cffFont != null)
            {
                genericFont = cffFont;
                isEmbedded  = true;
            }
            else
            {
                FontMapping <BaseFont> mapping = FontMappers.Instance.GetBaseFont(BaseFont, fd);
                genericFont = mapping.Font;

                if (mapping.IsFallback)
                {
                    Debug.WriteLine($"warn: Using fallback font {genericFont.Name} for {BaseFont}");
                }
                isEmbedded = false;
            }
            ReadEncoding();
            fontMatrixTransform = FontMatrix;
            fontMatrixTransform = fontMatrixTransform.PreConcat(SKMatrix.CreateScale(1000, 1000));
        }
Exemple #2
0
        protected override void OnDrawSample(SKCanvas canvas, int width, int height)
        {
            canvas.Clear(SKColors.White);

            var blockSize = 30;

            // create the path
            var path = new SKPath();
            // the rect must be offset as the path uses the center
            var rect = SKRect.Create(blockSize / -2, blockSize / -2, blockSize, blockSize);

            path.AddRect(rect);

            // move the path around: across 1 block
            var offsetMatrix = SKMatrix.CreateScale(2 * blockSize, blockSize);

            // each row, move across a bit / offset
            offsetMatrix = SKMatrix.Concat(offsetMatrix, SKMatrix.CreateSkew(0.5f, 0));

            // create the paint
            var paint = new SKPaint
            {
                PathEffect = SKPathEffect.Create2DPath(offsetMatrix, path),
                Color      = SKColors.LightGray
            };

            // draw a rectangle
            canvas.DrawRect(SKRect.Create(width + blockSize, height + blockSize), paint);
        }
        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);
        }
Exemple #4
0
        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;
            }
        }
Exemple #5
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);
        }
        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);
        }
Exemple #7
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();
            }
        }
        internal PdfType1Font(PdfDirectObject baseObject) : base(baseObject)
        {
            codeToBytesMap = new Dictionary <int, byte[]>();

            var       fd            = FontDescriptor;
            Type1Font t1            = null;
            bool      fontIsDamaged = false;

            if (fd != null)
            {
                // a Type1 font may contain a Type1C font
                var fontFile3 = fd.FontFile3;
                if (fontFile3 != null)
                {
                    throw new ArgumentException("Use PDType1CFont for FontFile3");
                }

                // or it may contain a PFB
                var fontFile = fd.FontFile;
                if (fontFile != null)
                {
                    try
                    {
                        t1 = LoadType1Font(fontFile);
                    }
                    catch (DamagedFontException e)
                    {
                        Debug.WriteLine($"warn: Can't read damaged embedded Type1 font {fd.FontName} {e}");
                        fontIsDamaged = true;
                    }
                    catch (IOException e)
                    {
                        Debug.WriteLine($"error: Can't read the embedded Type1 font {fd.FontName} {e}");
                        fontIsDamaged = true;
                    }
                }
            }
            isEmbedded = t1 != null;
            isDamaged  = fontIsDamaged;
            type1font  = t1;

            // find a generic font to use for rendering, could be a .pfb, but might be a .ttf
            if (type1font != null)
            {
                genericFont = type1font;
            }
            else
            {
                FontMapping <BaseFont> mapping = FontMappers.Instance.GetBaseFont(BaseFont, fd);
                genericFont = mapping.Font;

                if (mapping.IsFallback)
                {
                    Debug.WriteLine($"warn Using fallback font {genericFont.Name} for {BaseFont}");
                }
            }
            ReadEncoding();
            fontMatrixTransform = FontMatrix;
            fontMatrixTransform = fontMatrixTransform.PreConcat(SKMatrix.CreateScale(1000, 1000));
        }
Exemple #9
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;
            }
        }
Exemple #10
0
        private void OnPainting(object sender, SKPaintSurfaceEventArgs e)
        {
            var surface = e.Surface;
            var canvas  = surface.Canvas;

            var width  = e.Info.Width;
            var height = e.Info.Height;

            // clear the surface
            canvas.Clear(SKColors.White);

            // the page is not visible yet
            if (svg == null)
            {
                return;
            }

            // calculate the scaling need to fit to screen
            float canvasMin = Math.Min(width, height);
            float svgMax    = Math.Max(svg.Picture.CullRect.Width, svg.Picture.CullRect.Height);
            float scale     = canvasMin / svgMax;
            var   matrix    = SKMatrix.CreateScale(scale, scale);

            // draw the svg
            canvas.DrawPicture(svg.Picture, ref matrix);
        }
Exemple #11
0
        public static SKData EncodeSvg(FsPath svgFile, int maxWidht, int maxHeight, SKEncodedImageFormat format = SKEncodedImageFormat.Png)
        {
            var svg = new SKSvg();

            svg.Load(svgFile.ToString());

            if (svg.Picture == null)
            {
                return(SKData.Empty);
            }

            SKRect svgSize = svg.Picture.CullRect;

            (int renderWidth, int renderHeight, float scale)sizeData = CalcNewSize(svgSize, maxWidht, maxHeight);

            var matrix = SKMatrix.CreateScale(sizeData.scale, sizeData.scale);

            using (SKBitmap bitmap = new SKBitmap(sizeData.renderWidth, sizeData.renderHeight))
            {
                using (SKCanvas canvas = new SKCanvas(bitmap))
                {
                    canvas.DrawPicture(svg.Picture, ref matrix);
                    canvas.Flush();
                }

                using (SKImage image = SKImage.FromBitmap(bitmap))
                {
                    return(image.Encode(format, 100));
                }
            }
        }
        public void ScaleToMatrixIsCorrect()
        {
            var m   = SKMatrix.CreateScale(3.5f, 3.5f);
            var rsm = SKRotationScaleMatrix.CreateScale(3.5f).ToMatrix();

            Assert.Equal(m.Values, rsm.Values);
        }
        /// <summary>
        /// Transform the images ready for download, optionally adding a watermark.
        /// </summary>
        /// <param name="input"></param>
        /// <param name="output"></param>
        /// <param name="waterMarkText"></param>
        public void TransformDownloadImageSync(string input, Stream output, IExportSettings config)
        {
            using SKImage img = SKImage.FromEncodedData(input);
            using var bitmap  = SKBitmap.FromImage(img);

            float maxSize      = config.MaxImageSize;
            var   resizeFactor = 1f;

            if (bitmap.Width > maxSize)
            {
                resizeFactor = maxSize / bitmap.Width;
            }
            else if (bitmap.Height > maxSize)
            {
                resizeFactor = maxSize / bitmap.Height;
            }

            var targetWidth  = (int)Math.Round(bitmap.Width * resizeFactor);
            var targetHeight = (int)Math.Round(bitmap.Height * resizeFactor);

            // First create a bitmap the right size.
            using var toBitmap = new SKBitmap(targetWidth, targetHeight, bitmap.ColorType, bitmap.AlphaType);
            using var canvas   = new SKCanvas(toBitmap);

            // Draw a bitmap rescaled
            canvas.SetMatrix(SKMatrix.CreateScale(resizeFactor, resizeFactor));
            canvas.DrawBitmap(bitmap, 0, 0);
            canvas.ResetMatrix();

            if (!string.IsNullOrEmpty(config.WatermarkText))
            {
                using var font  = SKTypeface.FromFamilyName("Arial");
                using var brush = new SKPaint
                      {
                          Typeface    = font,
                          TextSize    = 64.0f,
                          IsAntialias = true,
                          Color       = new SKColor(255, 255, 255, 255)
                      };

                var textWidth       = brush.MeasureText(config.WatermarkText);
                var textTargetWidth = targetWidth / 6f;
                var fontScale       = textTargetWidth / textWidth;

                brush.TextSize *= fontScale;

                // Offset by text width + 10%
                var rightOffSet = (textTargetWidth * 1.1f);

                canvas.DrawText(config.WatermarkText, targetWidth - rightOffSet, targetHeight - brush.TextSize, brush);
            }

            canvas.Flush();

            using var image = SKImage.FromBitmap(toBitmap);
            using var data  = image.Encode(SKEncodedImageFormat.Jpeg, 90);

            data.SaveTo(output);
        }
        /// <summary>
        /// Transform the images ready for download, optionally adding a watermark.
        /// </summary>
        /// <param name="input"></param>
        /// <param name="output"></param>
        /// <param name="waterMarkText"></param>
        public void TransformDownloadImage(string input, Stream output, string waterMarkText = null)
        {
            float maxSize      = 1600f;
            var   resizeFactor = 1f;

            using var codec    = SKCodec.Create(input);
            using var original = SKBitmap.Decode(codec);

            // TODO: Use LoadOrientedBitmap here.
            // First, auto-orient the bitmap
            using var bitmap = AutoOrient(original, codec.EncodedOrigin);

            if (bitmap.Width > maxSize)
            {
                resizeFactor = maxSize / bitmap.Width;
            }
            else if (bitmap.Height > maxSize)
            {
                resizeFactor = maxSize / bitmap.Height;
            }

            var targetWidth  = (int)Math.Round(bitmap.Width * resizeFactor);
            var targetHeight = (int)Math.Round(bitmap.Height * resizeFactor);

            // First create a bitmap the right size.
            using var toBitmap = new SKBitmap(targetWidth, targetHeight, bitmap.ColorType, bitmap.AlphaType);
            using var canvas   = new SKCanvas(toBitmap);

            // Draw a bitmap rescaled
            canvas.SetMatrix(SKMatrix.CreateScale(resizeFactor, resizeFactor));
            canvas.DrawBitmap(bitmap, 0, 0);
            canvas.ResetMatrix();

            using var font  = SKTypeface.FromFamilyName("Arial");
            using var brush = new SKPaint
                  {
                      Typeface    = font,
                      TextSize    = 64.0f,
                      IsAntialias = true,
                      Color       = new SKColor(255, 255, 255, 255)
                  };

            var textWidth       = brush.MeasureText(waterMarkText);
            var textTargetWidth = targetWidth / 6f;
            var fontScale       = textTargetWidth / textWidth;

            brush.TextSize *= fontScale;

            // Offset by text width + 10%
            var rightOffSet = (textTargetWidth * 1.1f);

            canvas.DrawText(waterMarkText, targetWidth - rightOffSet, targetHeight - brush.TextSize, brush);
            canvas.Flush();

            using var image = SKImage.FromBitmap(toBitmap);
            using var data  = image.Encode(SKEncodedImageFormat.Jpeg, 90);

            data.SaveTo(output);
        }
Exemple #15
0
        protected override void OnDrawSample(SKCanvas canvas, int width, int height)
        {
            const float textSize = 40;

            var alignments = new[] { SKTextAlign.Left, SKTextAlign.Center, SKTextAlign.Right };
            var warpings   = new[] { false, true };
            var hOffsets   = new[] { 0f, -textSize, textSize };
            var vOffsets   = new[] { 0f, textSize / 2, textSize };
            var text       = @"The quick brown fox jumps over the lazy dog!";

            canvas.Clear(SKColors.White);

            var index = animationIndex;

            // create a circular path
            using var path  = SKPath.ParseSvgPathData("M 32 128 A 64 64 0 1 1 224 128 A 64 64 0 1 1 32 128");
            using var paint = new SKPaint
                  {
                      IsAntialias = true,
                      TextAlign   = SKTextAlign.Center,
                      TextSize    = textSize,
                      StrokeWidth = 2
                  };

            // Fit path in window.
            path.Transform(SKMatrix.CreateScale(width / 256f, height / 256f));

            // Pick text-on-path parameters.
            var alignment = Pick(alignments, ref index);
            var hOffset   = Pick(hOffsets, ref index);
            var vOffset   = Pick(vOffsets, ref index);
            var warping   = Pick(warpings, ref index);

            // make sure the canvas is blank
            canvas.Clear(SKColors.SkyBlue);

            // draw the parameters
            paint.TextSize  = 16;
            paint.Color     = SKColors.White;
            paint.TextAlign = SKTextAlign.Left;
            canvas.DrawText($" Alignment: {alignment}", 0, paint.TextSize, paint);
            paint.TextAlign = SKTextAlign.Center;
            canvas.DrawText($"Warping: {(warping ? "on" : "off")}", width / 2f, paint.TextSize, paint);
            paint.TextAlign = SKTextAlign.Right;
            canvas.DrawText($"Offset: ({hOffset}, {vOffset}) ", width, paint.TextSize, paint);

            // draw the path
            paint.Color    = SKColors.Blue;
            paint.Style    = SKPaintStyle.Stroke;
            paint.TextSize = textSize;
            canvas.DrawPath(path, paint);

            // draw the text on the path
            paint.TextAlign = alignment;
            paint.Color     = SKColors.Black;
            paint.Style     = SKPaintStyle.Fill;
            canvas.DrawTextOnPath(text, path, new SKPoint(hOffset, vOffset), warping, paint);
        }
Exemple #16
0
 public override void Resize(int width, int height, bool zoomContent = true)
 {
     Canvas.ResetMatrix();
     base.Resize(width, height, zoomContent);
     Canvas.SetMatrix(
         SKMatrix.CreateScale(
             width / (float)IconsConstants.RenderSize,
             height / (float)IconsConstants.RenderSize));
 }
Exemple #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));
        }
Exemple #18
0
        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);
        }
Exemple #19
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);
        }
Exemple #20
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);
        }
Exemple #21
0
        private SKMatrix ComputeMatrix(SKSize size, SKPoint ptUL, SKPoint ptUR, SKPoint ptLL, SKPoint?ptLR = null)
        {
            // Scale transform
            SKMatrix S = SKMatrix.CreateScale(1 / size.Width, 1 / size.Height);

            // Affine transform
            SKMatrix A = new SKMatrix
            {
                ScaleX = ptUR.X - ptUL.X,
                SkewY  = ptUR.Y - ptUL.Y,
                SkewX  = ptLL.X - ptUL.X,
                ScaleY = ptLL.Y - ptUL.Y,
                TransX = ptUL.X,
                TransY = ptUL.Y,
                Persp2 = 1
            };

            // Non-Affine transform
            SKMatrix N = SKMatrix.CreateIdentity();

            if (ptLR.HasValue)
            {
                SKMatrix inverseA;
                A.TryInvert(out inverseA);
                SKPoint abPoint = inverseA.MapPoint(ptLR.Value);
                float   a       = abPoint.X;
                float   b       = abPoint.Y;

                float scaleX = a / (a + b - 1);
                float scaleY = b / (a + b - 1);

                N = new SKMatrix
                {
                    ScaleX = scaleX,
                    ScaleY = scaleY,
                    Persp0 = scaleX - 1,
                    Persp1 = scaleY - 1,
                    Persp2 = 1
                };
            }

            // Multiply S * N * A
            SKMatrix result = SKMatrix.CreateIdentity();

            SKMatrix.PostConcat(ref result, S);
            SKMatrix.PostConcat(ref result, N);
            SKMatrix.PostConcat(ref result, A);

            return(result);
        }
 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));
     }
 }
Exemple #23
0
        private SKMatrix GetScaleMatrix(SKPoint center, float radiusX, float radiusY)
        {
            if (radiusX > radiusY)
            {
                return(SKMatrix.CreateScale(radiusX / radiusY, 1f, center.X, center.Y));
            }

            if (radiusY > radiusX)
            {
                return(SKMatrix.CreateScale(1f, radiusY / radiusX, center.X, center.Y));
            }

            return(SKMatrix.CreateIdentity());
        }
        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);
        }
Exemple #25
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);
        }
        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);
        }
        /// <summary>
        /// 2本指での操作
        /// </summary>
        /// <param name="prevPoint"></param>
        /// <param name="newPoint"></param>
        /// <param name="pivotPoint"></param>
        /// <returns></returns>
        public SKMatrix TwoFingerManipulate(SKPoint prevPoint, SKPoint newPoint, SKPoint pivotPoint)
        {
            SKMatrix touchMatrix = SKMatrix.CreateIdentity();
            SKPoint  oldVector   = prevPoint - pivotPoint;
            SKPoint  newVector   = newPoint - pivotPoint;

            if (Mode == TouchManipulationMode.ScaleRotate ||
                Mode == TouchManipulationMode.ScaleDualRotate)
            {
                // Find angles from pivot point to touch points
                float oldAngle = (float)Math.Atan2(oldVector.Y, oldVector.X);
                float newAngle = (float)Math.Atan2(newVector.Y, newVector.X);

                // Calculate rotation matrix
                float angle = newAngle - oldAngle;
                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;
            }

            float scaleX = 1;
            float scaleY = 1;

            if (Mode == TouchManipulationMode.AnisotropicScale)
            {
                scaleX = newVector.X / oldVector.X;
                scaleY = newVector.Y / oldVector.Y;
            }
            else if (Mode == TouchManipulationMode.IsotropicScale ||
                     Mode == TouchManipulationMode.ScaleRotate ||
                     Mode == TouchManipulationMode.ScaleDualRotate)
            {
                scaleX = scaleY = Magnitude(newVector) / Magnitude(oldVector);
            }

            if (!float.IsNaN(scaleX) && !float.IsInfinity(scaleX) &&
                !float.IsNaN(scaleY) && !float.IsInfinity(scaleY))
            {
                //SKMatrix.PostConcat(ref touchMatrix,
                //   SKMatrix.CreateScale(scaleX, scaleY, pivotPoint.X, pivotPoint.Y));
                touchMatrix = touchMatrix.PostConcat(SKMatrix.CreateScale(scaleX, scaleY, pivotPoint.X, pivotPoint.Y));
            }

            return(touchMatrix);
        }
        public static SKMatrix ToSKMatrix(this IViewport viewport)
        {
            var mapCenterX         = (float)viewport.Width * 0.5f;
            var mapCenterY         = (float)viewport.Height * 0.5f;
            var invertedResolution = 1f / (float)viewport.Resolution;

            var matrix = SKMatrix.CreateScale(invertedResolution, invertedResolution, mapCenterX, mapCenterY);

            matrix = SKMatrix.Concat(matrix, SKMatrix.CreateScale(1, -1, 0, -mapCenterY)); // As a consequence images will be up side down :(
            if (viewport.IsRotated)
            {
                matrix = SKMatrix.Concat(matrix, SKMatrix.CreateRotationDegrees((float)-viewport.Rotation));
            }
            matrix = SKMatrix.Concat(matrix, SKMatrix.CreateTranslation((float)-viewport.Center.X, (float)-viewport.Center.Y));
            return(matrix);
        }
Exemple #29
0
        private void DrawGrid(SKCanvas canvas, double dx, double dy, double zx, double zy)
        {
            float gw = (float)_view.Width;
            float gh = (float)_view.Height;
            float cw = 15.0f;
            float ch = 15.0f;

            canvas.Save();
            canvas.Translate((float)dx, (float)dy);
            canvas.Scale((float)zx, (float)zy);

            var hlattice = SKMatrix.CreateScale(cw, ch);

            hlattice = hlattice.PreConcat(SKMatrix.CreateRotation((float)(Math.PI * 0.0 / 180.0)));

            var vlattice = SKMatrix.CreateScale(cw, ch);

            vlattice = vlattice.PreConcat(SKMatrix.CreateRotation((float)(Math.PI * 90.0 / 180.0)));

            using (var heffect = SKPathEffect.Create2DLine((float)(1.0 / zx), hlattice))
                using (var veffect = SKPathEffect.Create2DLine((float)(1.0 / zx), vlattice))
                    using (var hpaint = new SKPaint())
                        using (var vpaint = new SKPaint())
                        {
                            hpaint.IsAntialias = false;
                            hpaint.Color       = SKColors.LightGray;
                            hpaint.PathEffect  = heffect;
                            canvas.DrawRect(SKRect.Create(0.0f, ch, gw, gh - ch), hpaint);
                            vpaint.IsAntialias = false;
                            vpaint.Color       = SKColors.LightGray;
                            vpaint.PathEffect  = veffect;
                            canvas.DrawRect(SKRect.Create(cw, 0.0f, gw - cw, gh), vpaint);
                        }

            using (SKPaint strokePaint = new SKPaint())
            {
                strokePaint.IsAntialias = false;
                strokePaint.StrokeWidth = (float)(1.0 / zx);
                strokePaint.Color       = SKColors.Red;
                strokePaint.Style       = SKPaintStyle.Stroke;
                canvas.DrawRect(SKRect.Create(0.0f, 0.0f, gw, gh), strokePaint);
            }

            canvas.Restore();
        }
Exemple #30
0
        public static void RenderSvg(SKSvg svg, Stream outStream, SKEncodedImageFormat skFormat, int minSize,
                                     int multiplier)
        {
            SKRect svgSize   = svg.Picture.CullRect;
            float  svgMax    = Math.Max(svgSize.Width, svgSize.Height);
            float  canvasMin = minSize * multiplier;
            float  scale     = canvasMin / svgMax;
            var    matrix    = SKMatrix.CreateScale(scale, scale);
            var    bitmap    = new SKBitmap((int)(svgSize.Width * scale), (int)(svgSize.Height * scale));
            var    canvas    = new SKCanvas(bitmap);

            canvas.Clear();
            canvas.DrawPicture(svg.Picture, ref matrix);
            canvas.Flush();
            var    image = SKImage.FromBitmap(bitmap);
            SKData data  = image.Encode(skFormat, 100);

            data.SaveTo(outStream);
        }