Example #1
0
 private static void ClearTransformedBounds(IVisual visual)
 {
     foreach (var e in visual.GetSelfAndVisualDescendents())
     {
         BoundsTracker.SetTransformedBounds((Visual)visual, null);
     }
 }
Example #2
0
        private static void Deindex(Scene scene, VisualNode node)
        {
            scene.Remove(node);
            node.SubTreeUpdated = true;

            scene.Layers[node.LayerRoot].Dirty.Add(node.Bounds);

            if (node.Visual is Visual v)
            {
                BoundsTracker.SetTransformedBounds(v, null);
            }

            foreach (VisualNode child in node.Children)
            {
                var geometry = child as IDrawOperation;

                if (child is VisualNode visual)
                {
                    Deindex(scene, visual);
                }
            }

            if (node.LayerRoot == node.Visual && node.Visual != scene.Root.Visual)
            {
                scene.Layers.Remove(node.LayerRoot);
            }
        }
Example #3
0
        /// <summary>
        /// Renders the specified visual.
        /// </summary>
        /// <param name="visual">The visual to render.</param>
        /// <param name="context">The drawing context.</param>
        /// <param name="clipRect">
        /// The current clip rect, in coordinates relative to <paramref name="visual"/>.
        /// </param>
        private static void Render(this DrawingContext context, IVisual visual, Rect clipRect)
        {
            var opacity      = visual.Opacity;
            var clipToBounds = visual.ClipToBounds;
            var bounds       = new Rect(visual.Bounds.Size);

            if (visual.IsVisible && opacity > 0)
            {
                var m = Matrix.CreateTranslation(visual.Bounds.Position);

                var renderTransform = Matrix.Identity;

                if (visual.RenderTransform != null)
                {
                    var origin = visual.RenderTransformOrigin.ToPixels(new Size(visual.Bounds.Width, visual.Bounds.Height));
                    var offset = Matrix.CreateTranslation(origin);
                    renderTransform = (-offset) * visual.RenderTransform.Value * (offset);
                }

                m = renderTransform * m;

                if (clipToBounds)
                {
                    clipRect = clipRect.Intersect(new Rect(visual.Bounds.Size));
                }

                using (context.PushPostTransform(m))
                    using (context.PushOpacity(opacity))
                        using (clipToBounds ? context.PushClip(bounds) : default(DrawingContext.PushedState))
                            using (visual.Clip != null ? context.PushGeometryClip(visual.Clip) : default(DrawingContext.PushedState))
                                using (visual.OpacityMask != null ? context.PushOpacityMask(visual.OpacityMask, bounds) : default(DrawingContext.PushedState))
                                    using (context.PushTransformContainer())
                                    {
                                        visual.Render(context);
                                        var transformed =
                                            new TransformedBounds(bounds, new Rect(), context.CurrentContainerTransform);
                                        if (visual is Visual)
                                        {
                                            BoundsTracker.SetTransformedBounds((Visual)visual, transformed);
                                        }

                                        var lst = GetSortedVisualList(visual.VisualChildren);

                                        foreach (var child in lst)
                                        {
                                            var childBounds = GetTransformedBounds(child);

                                            if (!child.ClipToBounds || clipRect.Intersects(childBounds))
                                            {
                                                var childClipRect = clipRect.Translate(-childBounds.Position);
                                                context.Render(child, childClipRect);
                                            }
                                        }

                                        ReturnListToPool(lst);
                                    }
            }
        }
Example #4
0
        private static void Update(DrawingContext context, Scene scene, VisualNode node, Rect clip, bool forceRecurse)
        {
            var visual       = node.Visual;
            var opacity      = visual.Opacity;
            var clipToBounds = visual.ClipToBounds;
            var bounds       = new Rect(visual.Bounds.Size);
            var contextImpl  = (DeferredDrawingContextImpl)context.PlatformImpl;

            contextImpl.Layers.Find(node.LayerRoot)?.Dirty.Add(node.Bounds);

            if (visual.IsVisible)
            {
                var m = Matrix.CreateTranslation(visual.Bounds.Position);

                var renderTransform = Matrix.Identity;

                if (visual.RenderTransform != null)
                {
                    var origin = visual.RenderTransformOrigin.ToPixels(new Size(visual.Bounds.Width, visual.Bounds.Height));
                    var offset = Matrix.CreateTranslation(origin);
                    renderTransform = (-offset) * visual.RenderTransform.Value * (offset);
                }

                m = renderTransform * m;

                using (contextImpl.BeginUpdate(node))
                    using (context.PushPostTransform(m))
                        using (context.PushTransformContainer())
                        {
                            var clipBounds = bounds.TransformToAABB(contextImpl.Transform).Intersect(clip);

                            forceRecurse = forceRecurse ||
                                           node.Transform != contextImpl.Transform ||
                                           node.ClipBounds != clipBounds;

                            node.Transform    = contextImpl.Transform;
                            node.ClipBounds   = clipBounds;
                            node.ClipToBounds = clipToBounds;
                            node.GeometryClip = visual.Clip?.PlatformImpl;
                            node.Opacity      = opacity;

                            // TODO: Check equality between node.OpacityMask and visual.OpacityMask before assigning.
                            node.OpacityMask = visual.OpacityMask?.ToImmutable();

                            if (ShouldStartLayer(visual))
                            {
                                if (node.LayerRoot != visual)
                                {
                                    MakeLayer(scene, node);
                                }
                                else
                                {
                                    UpdateLayer(node, scene.Layers[node.LayerRoot]);
                                }
                            }
                            else if (node.LayerRoot == node.Visual && node.Parent != null)
                            {
                                ClearLayer(scene, node);
                            }

                            if (node.ClipToBounds)
                            {
                                clip = clip.Intersect(node.ClipBounds);
                            }

                            try
                            {
                                visual.Render(context);
                            }
                            catch { }

                            if (visual is Visual)
                            {
                                var transformed = new TransformedBounds(new Rect(visual.Bounds.Size), clip, node.Transform);
                                BoundsTracker.SetTransformedBounds((Visual)visual, transformed);
                            }

                            if (forceRecurse)
                            {
                                foreach (var child in visual.VisualChildren.OrderBy(x => x, ZIndexComparer.Instance))
                                {
                                    var childNode = scene.FindNode(child) ?? CreateNode(scene, child, node);
                                    Update(context, scene, (VisualNode)childNode, clip, forceRecurse);
                                }

                                node.SubTreeUpdated = true;
                                contextImpl.TrimChildren();
                            }
                        }
            }
        }
Example #5
0
        private void Render(DrawingContext context, IVisual visual, Rect clipRect)
        {
            var opacity      = visual.Opacity;
            var clipToBounds = visual.ClipToBounds;
            var bounds       = new Rect(visual.Bounds.Size);

            if (visual.IsVisible && opacity > 0)
            {
                var m = Matrix.CreateTranslation(visual.Bounds.Position);

                var renderTransform = Matrix.Identity;

                if (visual.RenderTransform != null)
                {
                    var origin = visual.RenderTransformOrigin.ToPixels(new Size(visual.Bounds.Width, visual.Bounds.Height));
                    var offset = Matrix.CreateTranslation(origin);
                    renderTransform = (-offset) * visual.RenderTransform.Value * (offset);
                }

                m = renderTransform * m;

                if (clipToBounds)
                {
                    clipRect = clipRect.Intersect(new Rect(visual.Bounds.Size));
                }

                using (context.PushPostTransform(m))
                    using (context.PushOpacity(opacity))
                        using (clipToBounds ? context.PushClip(bounds) : default(DrawingContext.PushedState))
                            using (visual.Clip != null ? context.PushGeometryClip(visual.Clip) : default(DrawingContext.PushedState))
                                using (visual.OpacityMask != null ? context.PushOpacityMask(visual.OpacityMask, bounds) : default(DrawingContext.PushedState))
                                    using (context.PushTransformContainer())
                                    {
                                        visual.Render(context);

#pragma warning disable 0618
                                        var transformed =
                                            new TransformedBounds(bounds, new Rect(), context.CurrentContainerTransform);
#pragma warning restore 0618

                                        if (visual is Visual)
                                        {
                                            BoundsTracker.SetTransformedBounds((Visual)visual, transformed);
                                        }

                                        foreach (var child in visual.VisualChildren.OrderBy(x => x, ZIndexComparer.Instance))
                                        {
                                            var childBounds = GetTransformedBounds(child);

                                            if (!child.ClipToBounds || clipRect.Intersects(childBounds))
                                            {
                                                var childClipRect = clipRect.Translate(-childBounds.Position);
                                                Render(context, child, childClipRect);
                                            }
                                            else
                                            {
                                                ClearTransformedBounds(child);
                                            }
                                        }
                                    }
            }

            if (!visual.IsVisible)
            {
                ClearTransformedBounds(visual);
            }
        }