/// <summary> /// Creates and add 2 layers for ImageBrush background /// </summary> /// <param name="fullArea">The full area available (includes the border)</param> /// <param name="insideArea">The "inside" of the border (excludes the border)</param> /// <param name="layer">The layer in which the image layers will be added</param> /// <param name="sublayers">List of layers to keep all references</param> /// <param name="insertionIndex">Where in the layer the new layers will be added</param> /// <param name="imageBrush">The ImageBrush containing all the image properties (UIImage, Stretch, AlignmentX, etc.)</param> /// <param name="fillMask">Optional mask layer (for when we use rounded corners)</param> private static void CreateImageBrushLayers(CGRect fullArea, CGRect insideArea, CALayer layer, List <CALayer> sublayers, ref int insertionIndex, ImageBrush imageBrush, CAShapeLayer fillMask) { var uiImage = imageBrush.ImageSource.ImageData; // This layer is the one we apply the mask on. It's the full size of the shape because the mask is as well. var imageContainerLayer = new CALayer { Frame = fullArea, Mask = fillMask, BackgroundColor = new CGColor(0, 0, 0, 0), MasksToBounds = true, }; var imageFrame = imageBrush.GetArrangedImageRect(uiImage.Size, insideArea).ToCGRect(); // This is the layer with the actual image in it. Its frame is the inside of the border. var imageLayer = new CALayer { Contents = uiImage.CGImage, Frame = imageFrame, MasksToBounds = true, }; imageContainerLayer.AddSublayer(imageLayer); sublayers.Add(imageLayer); layer.InsertSublayer(imageContainerLayer, insertionIndex++); sublayers.Add(imageContainerLayer); }
private static Rect CreateImageLayer(Compositor compositor, CompositeDisposable disposables, Thickness borderThickness, Rect adjustedArea, CompositionSpriteShape backgroundShape, Rect backgroundArea, ImageBrush imgBackground) { imgBackground.Subscribe(imageData => { if (imageData.Error is null) { var surfaceBrush = compositor.CreateSurfaceBrush(imageData.Value); var sourceImageSize = new Size(imageData.Value.Image.Width, imageData.Value.Image.Height); // We reduce the adjustedArea again so that the image is inside the border (like in Windows) var imageArea = adjustedArea.DeflateBy(borderThickness); backgroundArea = imgBackground.GetArrangedImageRect(sourceImageSize, imageArea); // surfaceBrush.Offset = new Vector2((float)imageFrame.Left, (float)imageFrame.Top); var matrix = Matrix3x2.CreateScale((float)(backgroundArea.Width / sourceImageSize.Width), (float)(backgroundArea.Height / sourceImageSize.Height)); matrix *= Matrix3x2.CreateTranslation((float)backgroundArea.Left, (float)backgroundArea.Top); if (imgBackground.Transform != null) { matrix *= imgBackground.Transform.ToMatrix(new Point()); } surfaceBrush.TransformMatrix = matrix; backgroundShape.FillBrush = surfaceBrush; } else { backgroundShape.FillBrush = null; } }).DisposeWith(disposables); return(backgroundArea); }