public static Rect ToRect(ISvgRect rect)
        {
            if (rect == null)
            {
                return Rect.Empty;
            }

            return new Rect(rect.X, rect.Y, rect.Width, rect.Height);
        }
Beispiel #2
0
 public void Resize()
 {
     // TODO: Invalidate! Fire SVGResize
     x = null;
     y = null;
     width = null;
     height = null;
     currentView = null;
     cachedViewBoxTransform = null;
     viewport = null;
     svgFitToViewBox = null;
     svgFitToViewBox = new SvgFitToViewBox(this);
     if (this == OwnerDocument.RootElement)
     {
         // TODO
     }
     else
     {
         (OwnerDocument.RootElement as SvgSvgElement).Resize();
     }
 }
Beispiel #3
0
 /// <summary>
 /// Returns true if the rendered content of the given element intersects the supplied 
 /// rectangle, honoring the 'pointer-events' property value on each candidate graphics 
 /// element.
 /// </summary>
 /// <param name="element">The element on which to perform the given test.</param>
 /// <param name="rect">The test rectangle. The values are in the initial coordinate system 
 /// for the current 'svg' element.</param>
 /// <returns>True or false, depending on whether the given element intersects the supplied 
 /// rectangle.</returns>
 public bool CheckIntersection(ISvgElement element, ISvgRect rect)
 {
     throw new NotImplementedException();
 }
Beispiel #4
0
 /// <summary>
 /// Returns the list of graphics elements whose rendered content intersects the supplied 
 /// rectangle, honoring the 'pointer-events' property value on each candidate graphics 
 /// element.
 /// </summary>
 /// <param name="rect">The test rectangle. The values are in the initial coordinate 
 /// system for the current 'svg' element.</param>
 /// <param name="referenceElement">If not null, then only return elements whose drawing 
 /// order has them below the given reference element.</param>
 /// <returns>A list of Elements whose content intersects the supplied rectangle.</returns>
 public XmlNodeList GetIntersectionList(ISvgRect rect, ISvgElement referenceElement)
 {
     throw new NotImplementedException();
 }
        protected void SetClip(GdiGraphics graphics)
        {
            if (_svgElement == null)
            {
                return;
            }

            SvgRenderingHint hint = _svgElement.RenderingHint;

            // todo: should we correct the clipping to adjust to the off-one-pixel drawing?
            graphics.TranslateClip(1, 1);

            #region Clip with clip
            // see http://www.w3.org/TR/SVG/masking.html#OverflowAndClipProperties
            if (_svgElement is ISvgSvgElement || _svgElement is ISvgMarkerElement ||
                _svgElement is ISvgSymbolElement || _svgElement is ISvgPatternElement)
            {
                // check overflow property
                CssValue overflow = _svgElement.GetComputedCssValue("overflow", string.Empty) as CssValue;
                // TODO: clip can have "rect(10 10 auto 10)"
                CssPrimitiveValue clip = _svgElement.GetComputedCssValue("clip", string.Empty) as CssPrimitiveValue;

                string sOverflow = null;

                if (overflow != null || overflow.CssText == "")
                {
                    sOverflow = overflow.CssText;
                }
                else
                {
                    if (this is ISvgSvgElement)
                    {
                        sOverflow = "hidden";
                    }
                }

                if (sOverflow != null)
                {
                    // "If the 'overflow' property has a value other than hidden or scroll, the property has no effect (i.e., a clipping rectangle is not created)."
                    if (sOverflow == "hidden" || sOverflow == "scroll")
                    {
                        RectangleF clipRect = RectangleF.Empty;
                        if (clip != null && clip.PrimitiveType == CssPrimitiveType.Rect)
                        {
                            if (_svgElement is ISvgSvgElement)
                            {
                                ISvgSvgElement svgElement = (ISvgSvgElement)_svgElement;
                                SvgRect        viewPort   = svgElement.Viewport as SvgRect;
                                clipRect = GdiConverter.ToRectangle(viewPort);
                                ICssRect clipShape = (CssRect)clip.GetRectValue();
                                if (clipShape.Top.PrimitiveType != CssPrimitiveType.Ident)
                                {
                                    clipRect.Y += (float)clipShape.Top.GetFloatValue(CssPrimitiveType.Number);
                                }
                                if (clipShape.Left.PrimitiveType != CssPrimitiveType.Ident)
                                {
                                    clipRect.X += (float)clipShape.Left.GetFloatValue(CssPrimitiveType.Number);
                                }
                                if (clipShape.Right.PrimitiveType != CssPrimitiveType.Ident)
                                {
                                    clipRect.Width = (clipRect.Right - clipRect.X) - (float)clipShape.Right.GetFloatValue(CssPrimitiveType.Number);
                                }
                                if (clipShape.Bottom.PrimitiveType != CssPrimitiveType.Ident)
                                {
                                    clipRect.Height = (clipRect.Bottom - clipRect.Y) - (float)clipShape.Bottom.GetFloatValue(CssPrimitiveType.Number);
                                }
                            }
                        }
                        else if (clip == null || (clip.PrimitiveType == CssPrimitiveType.Ident && clip.GetStringValue() == "auto"))
                        {
                            if (_svgElement is ISvgSvgElement)
                            {
                                ISvgSvgElement svgElement = (ISvgSvgElement)_svgElement;
                                SvgRect        viewPort   = svgElement.Viewport as SvgRect;
                                clipRect = GdiConverter.ToRectangle(viewPort);
                            }
                            else if (_svgElement is ISvgMarkerElement || _svgElement is ISvgSymbolElement ||
                                     _svgElement is ISvgPatternElement)
                            {
                                // TODO: what to do here?
                            }
                        }
                        if (clipRect != RectangleF.Empty)
                        {
                            graphics.SetClip(clipRect);
                        }
                    }
                }
            }
            #endregion

            #region Clip with clip-path

            // see: http://www.w3.org/TR/SVG/masking.html#EstablishingANewClippingPath

            if (hint == SvgRenderingHint.Shape || hint == SvgRenderingHint.Text ||
                hint == SvgRenderingHint.Clipping || hint == SvgRenderingHint.Masking ||
                hint == SvgRenderingHint.Containment || hint == SvgRenderingHint.Image)
            {
                CssPrimitiveValue clipPath = _svgElement.GetComputedCssValue("clip-path", string.Empty) as CssPrimitiveValue;

                if (clipPath != null && clipPath.PrimitiveType == CssPrimitiveType.Uri)
                {
                    string absoluteUri = _svgElement.ResolveUri(clipPath.GetStringValue());

                    SvgClipPathElement eClipPath = _svgElement.OwnerDocument.GetNodeByUri(absoluteUri) as SvgClipPathElement;

                    if (eClipPath != null)
                    {
                        GraphicsPath gpClip = CreateClippingRegion(graphics, eClipPath);

                        RectangleF clipBounds = gpClip != null?gpClip.GetBounds() : RectangleF.Empty;

                        if (clipBounds.Width.Equals(0) || clipBounds.Height.Equals(0))
                        {
                            return;
                        }

                        SvgUnitType pathUnits = (SvgUnitType)eClipPath.ClipPathUnits.AnimVal;

                        if (pathUnits == SvgUnitType.ObjectBoundingBox)
                        {
                            SvgTransformableElement transElement = _svgElement as SvgTransformableElement;

                            if (transElement != null)
                            {
                                ISvgRect bbox = transElement.GetBBox();

                                // scale clipping path
                                Matrix matrix = new Matrix();
                                matrix.Scale((float)bbox.Width, (float)bbox.Height);
                                gpClip.Transform(matrix);
                                graphics.SetClip(gpClip);

                                // offset clip
                                graphics.TranslateClip((float)bbox.X, (float)bbox.Y);
                            }
                            else
                            {
                                throw new NotImplementedException("clip-path with SvgUnitType.ObjectBoundingBox "
                                                                  + "not supported for this type of element: " + _svgElement.GetType());
                            }
                        }
                        else
                        {
                            graphics.SetClip(gpClip);
                        }

                        gpClip.Dispose();
                        gpClip = null;
                    }
                }
            }
            #endregion
        }
Beispiel #6
0
 /// <summary>
 /// Returns true if the rendered content of the given element is entirely contained within 
 /// the supplied rectangle, honoring the 'pointer-events' property value on each candidate 
 /// graphics element.
 /// </summary>
 /// <param name="element">The element on which to perform the given test</param>
 /// <param name="rect">The test rectangle. The values are in the initial coordinate system 
 /// for the current 'svg' element.</param>
 /// <returns>True or false, depending on whether the given element is enclosed by the 
 /// supplied rectangle.</returns>
 public bool CheckEnclosure(ISvgElement element, ISvgRect rect)
 {
     throw new NotImplementedException();
 }
Beispiel #7
0
        public override void BeforeRender(WpfDrawingRenderer renderer)
        {
            base.BeforeRender(renderer);

            _idElement = string.Empty;

            WpfDrawingContext context = renderer.Context;

            DrawingGroup currentGroup = context.Peek();

            if (currentGroup == null)
            {
                throw new InvalidOperationException("An existing group is expected.");
            }

            if (currentGroup == context.Root)
            {
                if (context.IsFragment)
                {
                    // Do not add extra layer to fragments...
                    _drawGroup = currentGroup;
                }
                else
                {
                    _drawGroup = new DrawingGroup();
                    SvgObject.SetName(_drawGroup, SvgObject.DrawLayer);
                    if (context.IncludeRuntime)
                    {
                        SvgLink.SetKey(_drawGroup, SvgObject.DrawLayer);
                    }

                    currentGroup.Children.Add(_drawGroup);
                    context.Push(_drawGroup);
                }
            }
            else
            {
                _drawGroup = new DrawingGroup();
                currentGroup.Children.Add(_drawGroup);
                context.Push(_drawGroup);
            }

            SvgPatternElement svgElm = (SvgPatternElement)_svgElement;

            _idElement = svgElm.Id;
            if (!string.IsNullOrWhiteSpace(_idElement))
            {
                context.AddUrl(_idElement);
            }

            double x      = Math.Round(svgElm.X.AnimVal.Value, 4);
            double y      = Math.Round(svgElm.Y.AnimVal.Value, 4);
            double width  = Math.Round(svgElm.Width.AnimVal.Value, 4);
            double height = Math.Round(svgElm.Height.AnimVal.Value, 4);

            if (width < 0 || height < 0)
            {
                // For invalid dimension, prevent the drawing of the children...
                _isRecursive = true;
                return;
            }

            Rect elmRect = new Rect(x, y, width, height);

//            XmlNode parentNode = _svgElement.ParentNode;

            ISvgFitToViewBox fitToView = svgElm as ISvgFitToViewBox;
            ISvgAnimatedPreserveAspectRatio preserveAspectRatio = null;

            if (fitToView != null && fitToView.PreserveAspectRatio != null)
            {
                preserveAspectRatio = fitToView.PreserveAspectRatio;
                ISvgAnimatedRect animRect = fitToView.ViewBox;
                if (animRect != null)
                {
                    ISvgRect viewRect = animRect.AnimVal;
                    if (viewRect != null)
                    {
                        Rect wpfViewRect = WpfConvert.ToRect(viewRect);
                        if (!wpfViewRect.IsEmpty && wpfViewRect.Width > 0 && wpfViewRect.Height > 0)
                        {
                            elmRect = wpfViewRect;
                        }
                    }
                }
            }

            Transform transform   = null;
            var       aspectRatio = (preserveAspectRatio != null) ? preserveAspectRatio.AnimVal : null;

            if (aspectRatio != null /* && aspectRatio.Align == SvgPreserveAspectRatioType.None*/)
            {
                FitToViewbox(context, elmRect);

                transform = this.Transform;
                if (transform != null)
                {
                    _drawGroup.Transform = transform;
                }
            }
        }
Beispiel #8
0
        public override void BeforeRender(WpfDrawingRenderer renderer)
        {
            base.BeforeRender(renderer);

            WpfDrawingContext context = renderer.Context;

            if (context.Count == 0)
            {
                _drawGroup = new DrawingGroup();
                context.Push(_drawGroup);
                context.Root = _drawGroup;
            }
            else if (context.Count == 1)
            {
                DrawingGroup currentGroup = context.Peek();

                if (currentGroup == null)
                {
                    throw new InvalidOperationException("An existing group is expected.");
                }

                if (currentGroup == context.Root)
                {
                    if (context.IsFragment)
                    {
                        // Do not add extra layer to fragments...
                        _drawGroup = currentGroup;
                    }
                    else
                    {
                        _drawGroup = new DrawingGroup();
                        SvgObject.SetName(_drawGroup, SvgObject.DrawLayer);
                        if (context.IncludeRuntime)
                        {
                            SvgLink.SetKey(_drawGroup, SvgObject.DrawLayer);
                        }

                        currentGroup.Children.Add(_drawGroup);
                        context.Push(_drawGroup);
                    }
                }
                else
                {
                    _drawGroup = new DrawingGroup();
                    currentGroup.Children.Add(_drawGroup);
                    context.Push(_drawGroup);
                }
            }
            else
            {
                _drawGroup = new DrawingGroup();
                DrawingGroup currentGroup = context.Peek();

                if (currentGroup == null)
                {
                    throw new InvalidOperationException("An existing group is expected.");
                }

                currentGroup.Children.Add(_drawGroup);
                context.Push(_drawGroup);
            }

            SvgSvgElement svgElm = (SvgSvgElement)_svgElement;

            double x      = Math.Round(svgElm.X.AnimVal.Value, 4);
            double y      = Math.Round(svgElm.Y.AnimVal.Value, 4);
            double width  = Math.Round(svgElm.Width.AnimVal.Value, 4);
            double height = Math.Round(svgElm.Height.AnimVal.Value, 4);

            if (width < 0 || height < 0)
            {
                // For invalid dimension, prevent the drawing of the children...
                _isRecursive = true;
                return;
            }

            Rect elmRect = new Rect(x, y, width, height);

            XmlNode parentNode = _svgElement.ParentNode;

            ISvgFitToViewBox fitToView = svgElm as ISvgFitToViewBox;
            ISvgAnimatedPreserveAspectRatio preserveAspectRatio = null;

            if (fitToView != null && fitToView.PreserveAspectRatio != null)
            {
                preserveAspectRatio = fitToView.PreserveAspectRatio;
                ISvgAnimatedRect animRect = fitToView.ViewBox;
                if (animRect != null)
                {
                    ISvgRect viewRect = animRect.AnimVal;
                    if (viewRect != null)
                    {
                        Rect wpfViewRect = WpfConvert.ToRect(viewRect);
                        if (!wpfViewRect.IsEmpty && wpfViewRect.Width > 0 && wpfViewRect.Height > 0)
                        {
                            elmRect = wpfViewRect;
                        }
                    }
                }
            }

            Transform transform   = null;
            var       aspectRatio = (preserveAspectRatio != null) ? preserveAspectRatio.AnimVal : null;

            if (parentNode.NodeType != XmlNodeType.Document ||
                (aspectRatio != null && aspectRatio.Align == SvgPreserveAspectRatioType.None))
            {
                FitToViewbox(context, elmRect);

                transform = this.Transform;
                if (transform != null)
                {
                    _drawGroup.Transform = transform;
                }
            }

            if (!elmRect.IsEmpty && !elmRect.Width.Equals(0) && !elmRect.Height.Equals(0))
            {
                // Elements such as "pattern" are also rendered by this renderer, so we make sure we are
                // dealing with the root SVG element...
                if (parentNode != null && parentNode.NodeType == XmlNodeType.Document)
                {
                    _drawGroup.ClipGeometry = new RectangleGeometry(elmRect);
                }
                else
                {
                    if (transform != null)
                    {
                        // We have already applied the transform, which will translate to the start point...
                        if (transform is TranslateTransform)
                        {
                            //_drawGroup.ClipGeometry = new RectangleGeometry(
                            //    new Rect(0, 0, elmRect.Width, elmRect.Height));
                        }
                        else
                        {
                            _drawGroup.ClipGeometry = new RectangleGeometry(elmRect);
                        }
                    }
                    else
                    {
                        _drawGroup.ClipGeometry = new RectangleGeometry(elmRect);
                    }
                }
            }
        }
Beispiel #9
0
 /// <summary>
 /// Returns true if the rendered content of the given element is entirely contained within
 /// the supplied rectangle, honoring the 'pointer-events' property value on each candidate
 /// graphics element.
 /// </summary>
 /// <param name="element">The element on which to perform the given test</param>
 /// <param name="rect">The test rectangle. The values are in the initial coordinate system
 /// for the current 'svg' element.</param>
 /// <returns>True or false, depending on whether the given element is enclosed by the
 /// supplied rectangle.</returns>
 public bool CheckEnclosure(ISvgElement element, ISvgRect rect)
 {
     throw new NotImplementedException();
 }
Beispiel #10
0
 /// <summary>
 /// Returns true if the rendered content of the given element intersects the supplied
 /// rectangle, honoring the 'pointer-events' property value on each candidate graphics
 /// element.
 /// </summary>
 /// <param name="element">The element on which to perform the given test.</param>
 /// <param name="rect">The test rectangle. The values are in the initial coordinate system
 /// for the current 'svg' element.</param>
 /// <returns>True or false, depending on whether the given element intersects the supplied
 /// rectangle.</returns>
 public bool CheckIntersection(ISvgElement element, ISvgRect rect)
 {
     throw new NotImplementedException();
 }
Beispiel #11
0
 /// <summary>
 /// Returns the list of graphics elements whose rendered content is entirely contained
 /// within the supplied rectangle, honoring the 'pointer-events' property value on each
 /// candidate graphics element.
 /// </summary>
 /// <param name="rect">The test rectangle. The values are in the initial coordinate system
 /// for the current 'svg' element.</param>
 /// <param name="referenceElement">If not null, then only return elements whose drawing
 /// order has them below the given reference element.</param>
 /// <returns>A list of Elements whose content is enclosed by the supplied
 /// rectangle.</returns>
 public XmlNodeList GetEnclosureList(ISvgRect rect, ISvgElement referenceElement)
 {
     throw new NotImplementedException();
 }
        public override void BeforeRender(WpfDrawingRenderer renderer)
        {
            base.BeforeRender(renderer);

            WpfDrawingContext context = renderer.Context;

            _drawGroup = new DrawingGroup();

            if (context.Count == 0)
            {
                context.Push(_drawGroup);
                context.Root = _drawGroup;
            }
            else if (context.Count == 1)
            {
                DrawingGroup currentGroup = context.Peek();

                if (currentGroup == null)
                {
                    throw new InvalidOperationException("An existing group is expected.");
                }
                if (currentGroup == context.Root && !context.IsFragment)
                {
                    _drawGroup.SetValue(FrameworkElement.NameProperty, SvgObject.DrawLayer);
                    if (context.IncludeRuntime)
                    {
                        SvgLink.SetKey(_drawGroup, SvgObject.DrawLayer);
                    }
                }

                currentGroup.Children.Add(_drawGroup);
                context.Push(_drawGroup);
            }
            else
            {
                DrawingGroup currentGroup = context.Peek();

                if (currentGroup == null)
                {
                    throw new InvalidOperationException("An existing group is expected.");
                }

                currentGroup.Children.Add(_drawGroup);
                context.Push(_drawGroup);
            }

            SvgSvgElement svgElm = (SvgSvgElement)_svgElement;

            double x      = Math.Round(svgElm.X.AnimVal.Value, 4);
            double y      = Math.Round(svgElm.Y.AnimVal.Value, 4);
            double width  = Math.Round(svgElm.Width.AnimVal.Value, 4);
            double height = Math.Round(svgElm.Height.AnimVal.Value, 4);

            Rect elmRect = new Rect(x, y, width, height);

            //if (element.ParentNode is SvgElement)
            //{
            //    // TODO: should it be moved with x and y?
            //}

            XmlNode parentNode = _svgElement.ParentNode;

            //if (parentNode.NodeType == XmlNodeType.Document)
            {
                ISvgFitToViewBox fitToView = svgElm as ISvgFitToViewBox;
                if (fitToView != null)
                {
                    ISvgAnimatedRect animRect = fitToView.ViewBox;
                    if (animRect != null)
                    {
                        ISvgRect viewRect = animRect.AnimVal;
                        if (viewRect != null)
                        {
                            Rect wpfViewRect = WpfConvert.ToRect(viewRect);
                            if (!wpfViewRect.IsEmpty && wpfViewRect.Width > 0 && wpfViewRect.Height > 0)
                            {
                                elmRect = wpfViewRect;
                            }
                        }
                    }
                }
            }

            Transform transform = null;

            if (parentNode.NodeType != XmlNodeType.Document)
            {
                FitToViewbox(context, elmRect);

                transform = this.Transform;
                if (transform != null)
                {
                    _drawGroup.Transform = transform;
                }
            }

            //if (height > 0 && width > 0)
            //{
            //    ClipGeometry = new RectangleGeometry(elmRect);
            //}
            //Geometry clipGeom = this.ClipGeometry;
            //if (clipGeom != null)
            //{
            //    _drawGroup.ClipGeometry = clipGeom;
            //}

            if (((float)elmRect.Width != 0 && (float)elmRect.Height != 0))
            {
                // Elements such as "pattern" are also rendered by this renderer, so we make sure we are
                // dealing with the root SVG element...
                if (parentNode != null && parentNode.NodeType == XmlNodeType.Document)
                {
                    _drawGroup.ClipGeometry = new RectangleGeometry(elmRect);
                }
                else
                {
                    if (transform != null)
                    {
                        // We have already applied the transform, which will translate to the start point...
                        if (transform is TranslateTransform)
                        {
                            _drawGroup.ClipGeometry = new RectangleGeometry(
                                new Rect(0, 0, elmRect.Width, elmRect.Height));
                        }
                        else
                        {
                            _drawGroup.ClipGeometry = new RectangleGeometry(elmRect);
                        }
                    }
                    else
                    {
                        _drawGroup.ClipGeometry = new RectangleGeometry(elmRect);
                    }
                }

                //DrawingGroup animationGroup = context.Links;
                //if (animationGroup != null)
                //{
                //    animationGroup.ClipGeometry = clipGeom;
                //}
            }
        }
Beispiel #13
0
        public override Brush GetBrush(Rect elementBounds, WpfDrawingContext context, Transform viewTransform)
        {
            Rect bounds = elementBounds;

            DrawingGroup image = this.GetImage(context, bounds);

            if (image == null || image.Bounds.Width.Equals(0) || image.Bounds.Height.Equals(0))
            {
                return(null);
            }

            bool isUserSpace = true;

            if (_renderedElement.PatternContentUnits.AnimVal.Equals((ushort)SvgUnitType.ObjectBoundingBox))
            {
                bounds      = new Rect(0, 0, 1, 1);
                isUserSpace = false;
            }
            Rect destRect = GetDestRect(bounds);

            // Check for validity of the brush...
            if (destRect.Width.Equals(0) || destRect.Height.Equals(0) || destRect.IsEmpty)
            {
                return(null);
            }

            // Apply a scale if needed
            if (isUserSpace && image.Transform != null)
            {
                ISvgFitToViewBox fitToView = _renderedElement as ISvgFitToViewBox;
                if (fitToView != null && fitToView.ViewBox != null)
                {
                    ISvgAnimatedRect animRect = fitToView.ViewBox;
                    ISvgRect         viewRect = animRect.AnimVal;
                    if (viewRect != null)
                    {
                        Rect wpfViewRect = WpfConvert.ToRect(viewRect);
                        if (!wpfViewRect.IsEmpty && wpfViewRect.Width > 0 && wpfViewRect.Height > 0)
                        {
                            var scaleX = elementBounds.Width > 0 ? destRect.Width / wpfViewRect.Width : 1;
                            var scaleY = elementBounds.Height > 0 ? destRect.Height / wpfViewRect.Height : 1;

                            if (!scaleX.Equals(1) || !scaleY.Equals(1))
                            {
                                var currentTransform = image.Transform as ScaleTransform;
                                if (currentTransform != null)
                                {
                                    image.Transform = new ScaleTransform(scaleX, scaleY);
                                }
                            }
                        }
                    }
                }
            }

            DrawingBrush tb = new DrawingBrush(image);

            tb.Viewbox  = destRect;
            tb.Viewport = destRect;
            //tb.Viewbox = new Rect(0, 0, destRect.Width, destRect.Height);
            //tb.Viewport = new Rect(0, 0, bounds.Width, bounds.Height);
            tb.ViewboxUnits  = BrushMappingMode.Absolute;
            tb.ViewportUnits = isUserSpace ? BrushMappingMode.Absolute : BrushMappingMode.RelativeToBoundingBox;
            tb.TileMode      = TileMode.Tile;
//            tb.Stretch       = isUserSpace ? Stretch.Fill : Stretch.Uniform;

            if (isUserSpace)
            {
                MatrixTransform transform = GetTransformMatrix(image.Bounds, isUserSpace);
                if (transform != null && !transform.Matrix.IsIdentity)
                {
                    tb.Transform = transform;
                }
            }
            else
            {
                MatrixTransform transform = GetTransformMatrix(bounds, isUserSpace);
                if (transform != null && !transform.Matrix.IsIdentity)
                {
                    tb.RelativeTransform = transform;
                }
            }

            return(tb);
        }