예제 #1
0
        public void Update(Size finalSize, Thickness borderThickness, CornerRadius cornerRadius)
        {
            if (borderThickness.IsUniform && cornerRadius.IsUniform)
            {
                _backgroundGeometryCache = null;
                _borderGeometryCache     = null;
                _useComplexRendering     = false;
            }
            else
            {
                _useComplexRendering = true;

                var boundRect        = new Rect(finalSize);
                var innerRect        = boundRect.Deflate(borderThickness);
                var innerCoordinates = new BorderCoordinates(cornerRadius, borderThickness, false);

                StreamGeometry backgroundGeometry = null;

                if (innerRect.Width != 0 && innerRect.Height != 0)
                {
                    backgroundGeometry = new StreamGeometry();

                    using (var ctx = backgroundGeometry.Open())
                    {
                        CreateGeometry(ctx, innerRect, innerCoordinates);
                    }

                    _backgroundGeometryCache = backgroundGeometry;
                }
                else
                {
                    _backgroundGeometryCache = null;
                }

                if (boundRect.Width != 0 && innerRect.Height != 0)
                {
                    var outerCoordinates = new BorderCoordinates(cornerRadius, borderThickness, true);
                    var borderGeometry   = new StreamGeometry();

                    using (var ctx = borderGeometry.Open())
                    {
                        CreateGeometry(ctx, boundRect, outerCoordinates);

                        if (backgroundGeometry != null)
                        {
                            CreateGeometry(ctx, innerRect, innerCoordinates);
                        }
                    }

                    _borderGeometryCache = borderGeometry;
                }
                else
                {
                    _borderGeometryCache = null;
                }
            }
        }
예제 #2
0
        private static void CreateGeometry(StreamGeometryContext context, Rect boundRect, BorderCoordinates borderCoordinates)
        {
            var topLeft     = new Point(borderCoordinates.LeftTop, 0);
            var topRight    = new Point(boundRect.Width - borderCoordinates.RightTop, 0);
            var rightTop    = new Point(boundRect.Width, borderCoordinates.TopRight);
            var rightBottom = new Point(boundRect.Width, boundRect.Height - borderCoordinates.BottomRight);
            var bottomRight = new Point(boundRect.Width - borderCoordinates.RightBottom, boundRect.Height);
            var bottomLeft  = new Point(borderCoordinates.LeftBottom, boundRect.Height);
            var leftBottom  = new Point(0, boundRect.Height - borderCoordinates.BottomLeft);
            var leftTop     = new Point(0, borderCoordinates.TopLeft);


            if (topLeft.X > topRight.X)
            {
                var scaledX = borderCoordinates.LeftTop / (borderCoordinates.LeftTop + borderCoordinates.RightTop) * boundRect.Width;
                topLeft  = new Point(scaledX, topLeft.Y);
                topRight = new Point(scaledX, topRight.Y);
            }

            if (rightTop.Y > rightBottom.Y)
            {
                var scaledY = borderCoordinates.TopRight / (borderCoordinates.TopRight + borderCoordinates.BottomRight) * boundRect.Height;
                rightTop    = new Point(rightTop.X, scaledY);
                rightBottom = new Point(rightBottom.X, scaledY);
            }

            if (bottomRight.X < bottomLeft.X)
            {
                var scaledX = borderCoordinates.LeftBottom / (borderCoordinates.LeftBottom + borderCoordinates.RightBottom) * boundRect.Width;
                bottomRight = new Point(scaledX, bottomRight.Y);
                bottomLeft  = new Point(scaledX, bottomLeft.Y);
            }

            if (leftBottom.Y < leftTop.Y)
            {
                var scaledY = borderCoordinates.TopLeft / (borderCoordinates.TopLeft + borderCoordinates.BottomLeft) * boundRect.Height;
                leftBottom = new Point(leftBottom.X, scaledY);
                leftTop    = new Point(leftTop.X, scaledY);
            }

            var offset = new Vector(boundRect.TopLeft.X, boundRect.TopLeft.Y);

            topLeft     += offset;
            topRight    += offset;
            rightTop    += offset;
            rightBottom += offset;
            bottomRight += offset;
            bottomLeft  += offset;
            leftBottom  += offset;
            leftTop     += offset;

            context.BeginFigure(topLeft, true);

            //Top
            context.LineTo(topRight);

            //TopRight corner
            var radiusX = boundRect.TopRight.X - topRight.X;
            var radiusY = rightTop.Y - boundRect.TopRight.Y;

            if (radiusX != 0 || radiusY != 0)
            {
                context.ArcTo(rightTop, new Size(radiusY, radiusY), 0, false, SweepDirection.Clockwise);
            }

            //Right
            context.LineTo(rightBottom);

            //BottomRight corner
            radiusX = boundRect.BottomRight.X - bottomRight.X;
            radiusY = boundRect.BottomRight.Y - rightBottom.Y;
            if (radiusX != 0 || radiusY != 0)
            {
                context.ArcTo(bottomRight, new Size(radiusX, radiusY), 0, false, SweepDirection.Clockwise);
            }

            //Bottom
            context.LineTo(bottomLeft);

            //BottomLeft corner
            radiusX = bottomLeft.X - boundRect.BottomLeft.X;
            radiusY = boundRect.BottomLeft.Y - leftBottom.Y;
            if (radiusX != 0 || radiusY != 0)
            {
                context.ArcTo(leftBottom, new Size(radiusX, radiusY), 0, false, SweepDirection.Clockwise);
            }

            //Left
            context.LineTo(leftTop);

            //TopLeft corner
            radiusX = topLeft.X - boundRect.TopLeft.X;
            radiusY = leftTop.Y - boundRect.TopLeft.Y;

            if (radiusX != 0 || radiusY != 0)
            {
                context.ArcTo(topLeft, new Size(radiusX, radiusY), 0, false, SweepDirection.Clockwise);
            }

            context.EndFigure(true);
        }