Beispiel #1
0
        private static Vector CalculateTranslate(
            VisualBrush brush,
            Rect sourceRect,
            Rect destinationRect,
            Vector scale)
        {
            var x = 0.0;
            var y = 0.0;
            var size = sourceRect.Size * scale;

            switch (brush.AlignmentX)
            {
                case AlignmentX.Center:
                    x += (destinationRect.Width - size.Width) / 2;
                    break;
                case AlignmentX.Right:
                    x += destinationRect.Width - size.Width;
                    break;
            }

            switch (brush.AlignmentY)
            {
                case AlignmentY.Center:
                    y += (destinationRect.Height - size.Height) / 2;
                    break;
                case AlignmentY.Bottom:
                    y += destinationRect.Height - size.Height;
                    break;
            }

            return new Vector(x, y);
        }
Beispiel #2
0
        public VisualBrushImpl(
            VisualBrush brush,
            SharpDX.Direct2D1.RenderTarget target,
            Size targetSize)
        {
            var visual = brush.Visual;

            if (visual == null)
            {
                return;
            }

            var layoutable = visual as ILayoutable;

            if (layoutable?.IsArrangeValid == false)
            {
                layoutable.Measure(Size.Infinity);
                layoutable.Arrange(new Rect(layoutable.DesiredSize));
            }

            var tileMode = brush.TileMode;
            var sourceRect = brush.SourceRect.ToPixels(layoutable.Bounds.Size);
            var destinationRect = brush.DestinationRect.ToPixels(targetSize);
            var scale = brush.Stretch.CalculateScaling(destinationRect.Size, sourceRect.Size);
            var translate = CalculateTranslate(brush, sourceRect, destinationRect, scale);
            var intermediateSize = CalculateIntermediateSize(tileMode, targetSize, destinationRect.Size);
            var brtOpts = CompatibleRenderTargetOptions.None;

            // TODO: There are times where we don't need to draw an intermediate bitmap. Identify
            // them and directly use 'image' in those cases.
            using (var intermediate = new BitmapRenderTarget(target, brtOpts, intermediateSize))
            {
                Rect drawRect;
                var transform = CalculateIntermediateTransform(
                    tileMode,
                    sourceRect,
                    destinationRect,
                    scale,
                    translate,
                    out drawRect);
                var renderer = new RenderTarget(intermediate);

                using (var ctx = renderer.CreateDrawingContext())
                using (ctx.PushClip(drawRect))
                using (ctx.PushPostTransform(transform))
                {
                    intermediate.Clear(new Color4(0));
                    ctx.Render(visual);
                }

                this.PlatformBrush = new BitmapBrush(
                    target,
                    intermediate.Bitmap,
                    GetBitmapBrushProperties(brush),
                    GetBrushProperties(brush, destinationRect));
            }
        }
Beispiel #3
0
        public VisualBrushImpl(
            VisualBrush brush,
            RenderTarget target,
            Size targetSize)
        {
            var visual = brush.Visual;
            var layoutable = visual as ILayoutable;

            if (layoutable?.IsArrangeValid == false)
            {
                layoutable.Measure(Size.Infinity);
                layoutable.Arrange(new Rect(layoutable.DesiredSize));
            }

            var sourceRect = brush.SourceRect.ToPixels(layoutable.Bounds.Size);
            var destinationRect = brush.DestinationRect.ToPixels(targetSize);
            var bitmapSize = brush.TileMode == TileMode.None ? targetSize : destinationRect.Size;
            var scale = brush.Stretch.CalculateScaling(destinationRect.Size, sourceRect.Size);
            var translate = CalculateTranslate(brush, sourceRect, destinationRect, scale);
            var options = CompatibleRenderTargetOptions.None;

            using (var brt = new BitmapRenderTarget(target, options, bitmapSize.ToSharpDX()))
            {
                var renderer = new Renderer(brt);
                var transform = Matrix.CreateTranslation(-sourceRect.Position) *
                                Matrix.CreateScale(scale) *
                                Matrix.CreateTranslation(translate);

                Rect drawRect;

                if (brush.TileMode == TileMode.None)
                {
                    drawRect = destinationRect;
                    transform *= Matrix.CreateTranslation(destinationRect.Position);
                }
                else
                {
                    drawRect = new Rect(0, 0, destinationRect.Width, destinationRect.Height);
                }

                renderer.Render(visual, null, transform, drawRect);

                var result = new BitmapBrush(brt, brt.Bitmap);
                result.ExtendModeX = (brush.TileMode & TileMode.FlipX) != 0 ? ExtendMode.Mirror : ExtendMode.Wrap;
                result.ExtendModeY = (brush.TileMode & TileMode.FlipY) != 0 ? ExtendMode.Mirror : ExtendMode.Wrap;

                if (brush.TileMode != TileMode.None)
                {
                    result.Transform = SharpDX.Matrix3x2.Translation(
                        (float)destinationRect.X,
                        (float)destinationRect.Y);
                }

                PlatformBrush = result;
            }
        }
Beispiel #4
0
        public static SurfacePattern CreateVisualBrush(VisualBrush brush, Size targetSize)
        {
            var visual = brush.Visual;

            if (visual == null)
            {
                return null;
            }

            var layoutable = visual as ILayoutable;

            if (layoutable?.IsArrangeValid == false)
            {
                layoutable.Measure(Size.Infinity);
                layoutable.Arrange(new Rect(layoutable.DesiredSize));
            }

            // TODO: This is directly ported from Direct2D and could probably be made more
            // efficient on cairo by taking advantage of the fact that cairo has Extend.None.
            var tileMode = brush.TileMode;
            var sourceRect = brush.SourceRect.ToPixels(layoutable.Bounds.Size);
            var destinationRect = brush.DestinationRect.ToPixels(targetSize);
            var scale = brush.Stretch.CalculateScaling(destinationRect.Size, sourceRect.Size);
            var translate = CalculateTranslate(brush, sourceRect, destinationRect, scale);
            var intermediateSize = CalculateIntermediateSize(tileMode, targetSize, destinationRect.Size);
            
			using (var intermediate = new ImageSurface(Format.ARGB32, (int)intermediateSize.Width, (int)intermediateSize.Height))
            using (var context = new Context(intermediate))
            {
                Rect drawRect;
                var transform = CalculateIntermediateTransform(
                    tileMode,
                    sourceRect,
                    destinationRect,
                    scale,
                    translate,
                    out drawRect);
                var renderer = new Renderer(intermediate);

                context.Rectangle(drawRect.ToCairo());
                context.Clip();
                context.Transform(transform.ToCairo());
                renderer.Render(visual, new PlatformHandle(IntPtr.Zero, "RTB"), transform, drawRect);

                var result = new SurfacePattern(intermediate);

                if ((brush.TileMode & TileMode.FlipXY) != 0)
                {
                    // TODO: Currently always FlipXY as that's all cairo supports natively. 
                    // Support separate FlipX and FlipY by drawing flipped images to intermediate
                    // surface.
                    result.Extend = Extend.Reflect;
                }
                else
                {
                    result.Extend = Extend.Repeat;
                }

                if (brush.TileMode != TileMode.None)
                {
                    var matrix = result.Matrix;
                    matrix.InitTranslate(-destinationRect.X, -destinationRect.Y);
                    result.Matrix = matrix;
                }

                return result;
            }
        }
Beispiel #5
0
        public VisualBrushImpl(
            VisualBrush brush,
            RenderTarget target,
            Size targetSize)
        {
            var visual = brush.Visual;

            if (visual == null)
            {
                return;
            }

            var layoutable = visual as ILayoutable;

            if (layoutable?.IsArrangeValid == false)
            {
                layoutable.Measure(Size.Infinity);
                layoutable.Arrange(new Rect(layoutable.DesiredSize));
            }

            var tileMode = brush.TileMode;
            var sourceRect = brush.SourceRect.ToPixels(layoutable.Bounds.Size);
            var destinationRect = brush.DestinationRect.ToPixels(targetSize);
            var scale = brush.Stretch.CalculateScaling(destinationRect.Size, sourceRect.Size);
            var translate = CalculateTranslate(brush, sourceRect, destinationRect, scale);
            var intermediateSize = CalculateIntermediateSize(tileMode, targetSize, destinationRect.Size);
            var brtOpts = CompatibleRenderTargetOptions.None;

            // TODO: There are times where we don't need to draw an intermediate bitmap. Identify
            // them and directly use 'image' in those cases.
            using (var intermediate = new BitmapRenderTarget(target, brtOpts, intermediateSize))
            {
                Rect drawRect;
                var transform = CalculateIntermediateTransform(
                    tileMode,
                    sourceRect,
                    destinationRect,
                    scale,
                    translate,
                    out drawRect);
                var renderer = new Renderer(intermediate);

                renderer.Render(visual, null, transform, drawRect);

                this.PlatformBrush = new BitmapBrush(
                    target,
                    intermediate.Bitmap,
                    GetBitmapBrushProperties(brush),
                    GetBrushProperties(brush, destinationRect));
            }

            //var sourceRect = brush.SourceRect.ToPixels(layoutable.Bounds.Size);
            //var destinationRect = brush.DestinationRect.ToPixels(targetSize);
            //var bitmapSize = brush.TileMode == TileMode.None ? targetSize : destinationRect.Size;
            //var scale = brush.Stretch.CalculateScaling(destinationRect.Size, sourceRect.Size);
            //var translate = CalculateTranslate(brush, sourceRect, destinationRect, scale);
            //var options = CompatibleRenderTargetOptions.None;

            //using (var brt = new BitmapRenderTarget(target, options, bitmapSize.ToSharpDX()))
            //{
            //    var renderer = new Renderer(brt);
            //    var transform = Matrix.CreateTranslation(-sourceRect.Position) *
            //                    Matrix.CreateScale(scale) *
            //                    Matrix.CreateTranslation(translate);

            //    Rect drawRect;

            //    if (brush.TileMode == TileMode.None)
            //    {
            //        drawRect = destinationRect;
            //        transform *= Matrix.CreateTranslation(destinationRect.Position);
            //    }
            //    else
            //    {
            //        drawRect = new Rect(0, 0, destinationRect.Width, destinationRect.Height);
            //    }

            //    renderer.Render(visual, null, transform, drawRect);

            //    var result = new BitmapBrush(brt, brt.Bitmap);
            //    result.ExtendModeX = GetExtendModeX(brush.TileMode);
            //    result.ExtendModeY = GetExtendModeY(brush.TileMode);

            //    if (brush.TileMode != TileMode.None)
            //    {
            //        result.Transform = SharpDX.Matrix3x2.Translation(
            //            (float)destinationRect.X,
            //            (float)destinationRect.Y);
            //    }

            //    PlatformBrush = result;
            //}
        }