Пример #1
0
        private void SimpleRender(DrawingContext dc)
        {
            var useLayoutRounding = UseLayoutRounding;
            var dpi = DpiUtil.GetDpi(this);

            Brush brush;
            var   borderStyle = BorderStyle;

            var borders      = BorderThickness;
            var cornerRadius = CornerRadius;

            var outerCornerRadius = cornerRadius.TopLeft; // Already validated that all corners have the same radius
            var roundedCorners    = !DoubleUtil.IsZero(outerCornerRadius);

            var width  = RenderSize.Width;
            var height = RenderSize.Height;

            // Draw border
            if (!ThicknessUtil.IsZero(borders) && (brush = BorderBrush) != null)
            {
                var pen          = GetPen(brush, borderStyle, borders.Left, dpi.DpiScaleX, useLayoutRounding);
                var penThickness = pen.Thickness;

                double x    = penThickness * 0.5;
                var    rect = new Rect(x, x, width - penThickness, height - penThickness);

                if (roundedCorners)
                {
                    dc.DrawRoundedRectangle(null, pen, rect, outerCornerRadius, outerCornerRadius);
                }
                else
                {
                    dc.DrawRectangle(null, pen, rect);
                }
            }

            // Draw background in rectangle inside border.
            if ((brush = Background) != null)
            {
                // Intialize background
                Point ptTL, ptBR;

                if (useLayoutRounding)
                {
                    ptTL = new Point(UIElementUtil.RoundLayoutValue(borders.Left, dpi.DpiScaleX),
                                     UIElementUtil.RoundLayoutValue(borders.Top, dpi.DpiScaleY));
                    ptBR = new Point(width - UIElementUtil.RoundLayoutValue(borders.Right, dpi.DpiScaleX),
                                     height - UIElementUtil.RoundLayoutValue(borders.Bottom, dpi.DpiScaleY));
                }
                else
                {
                    ptTL = new Point(borders.Left, borders.Top);
                    ptBR = new Point(width - borders.Right, height - borders.Bottom);
                }

                // Do not draw background if the borders are so large that they overlap.
                if (ptBR.X > ptTL.X && ptBR.Y > ptTL.Y)
                {
                    if (roundedCorners)
                    {
                        // Determine the inner edge radius
                        var innerCornerRadius = Math.Max(0.0, outerCornerRadius - borders.Top * 0.5);
                        dc.DrawRoundedRectangle(brush, null, new Rect(ptTL, ptBR), innerCornerRadius, innerCornerRadius);
                    }
                    else
                    {
                        dc.DrawRectangle(brush, null, new Rect(ptTL, ptBR));
                    }
                }
            }
        }
Пример #2
0
        private void ComplexRender(DrawingContext dc)
        {
            Brush brush;
            var   width  = RenderSize.Width;
            var   height = RenderSize.Height;

            //Draw border
            if (!DoubleUtil.IsZero(width) && !DoubleUtil.IsZero(height) && (brush = BorderBrush) != null)
            {
                var useLayoutRounding = UseLayoutRounding;
                var dpi = DpiUtil.GetDpi(this);

                var    borders = BorderThickness;
                var    borderStyle = BorderStyle;
                var    radius = CornerRadius;
                double x, y;

                // Left Line
                if (!DoubleUtil.IsZero(borders.Left))
                {
                    if (leftPenCache == null)
                    {
                        leftPenCache = GetPen(brush, borderStyle, borders.Left, dpi.DpiScaleX, useLayoutRounding);
                    }

                    x = leftPenCache.Thickness * 0.5;
                    dc.DrawLine(leftPenCache, new Point(x, radius.TopLeft), new Point(x, height - radius.BottomLeft));
                }

                // Top Line
                if (!DoubleUtil.IsZero(borders.Top))
                {
                    if (topPenCache == null)
                    {
                        topPenCache = GetPen(brush, borderStyle, borders.Top, dpi.DpiScaleY, useLayoutRounding);
                    }

                    y = topPenCache.Thickness * 0.5;
                    dc.DrawLine(topPenCache, new Point(radius.TopLeft, y), new Point(width - radius.TopRight, y));
                }

                // Right Line
                if (!DoubleUtil.IsZero(borders.Right))
                {
                    if (rightPenCache == null)
                    {
                        rightPenCache = GetPen(brush, borderStyle, borders.Right, dpi.DpiScaleX, useLayoutRounding);
                    }

                    x = width - rightPenCache.Thickness * 0.5;
                    dc.DrawLine(rightPenCache, new Point(x, radius.TopRight), new Point(x, height - radius.BottomRight));
                }

                // Bottom Line
                if (!DoubleUtil.IsZero(borders.Bottom))
                {
                    if (bottomPenCache == null)
                    {
                        bottomPenCache = GetPen(brush, borderStyle, borders.Bottom, dpi.DpiScaleY, useLayoutRounding);
                    }

                    y = height - bottomPenCache.Thickness * 0.5;
                    dc.DrawLine(bottomPenCache, new Point(radius.BottomLeft, y), new Point(width - radius.BottomRight, y));
                }

                // Draw Rounded
                Pen pen;

                if (upperLeftCache != null && (pen = GetMaxPen(leftPenCache, topPenCache)) != null)
                {
                    dc.DrawGeometry(null, pen, upperLeftCache);
                }

                if (upperRightCache != null && (pen = GetMaxPen(topPenCache, rightPenCache)) != null)
                {
                    dc.DrawGeometry(null, pen, upperRightCache);
                }

                if (lowerRightCache != null && (pen = GetMaxPen(rightPenCache, bottomPenCache)) != null)
                {
                    dc.DrawGeometry(null, pen, lowerRightCache);
                }

                if (lowerLeftCache != null && (pen = GetMaxPen(bottomPenCache, leftPenCache)) != null)
                {
                    dc.DrawGeometry(null, pen, lowerLeftCache);
                }
            }

            // Draw background in rectangle inside border.
            if (backgroundGeometryCache != null && (brush = Background) != null)
            {
                dc.DrawGeometry(brush, null, backgroundGeometryCache);
            }
        }
Пример #3
0
        /// <summary>
        /// Border computes the position of its single child and applies its child's alignments to the child.
        /// </summary>
        /// <param name="finalSize">The size reserved for this element by the parent</param>
        /// <returns>The actual ink area of the element, typically the same as finalSize</returns>
        protected override Size ArrangeOverride(Size finalSize)
        {
            var borders = BorderThickness;

            if (UseLayoutRounding)
            {
                var dpi = DpiUtil.GetDpi(this);
                borders = new Thickness(UIElementUtil.RoundLayoutValue(borders.Left, dpi.DpiScaleX), UIElementUtil.RoundLayoutValue(borders.Top, dpi.DpiScaleY),
                                        UIElementUtil.RoundLayoutValue(borders.Right, dpi.DpiScaleX), UIElementUtil.RoundLayoutValue(borders.Bottom, dpi.DpiScaleY));
            }

            var boundRect = new Rect(finalSize);
            var innerRect = RectUtil.Deflate(boundRect, borders);

            //  arrange child
            var child = Child;

            if (child != null)
            {
                Rect childRect = RectUtil.Deflate(innerRect, Padding);
                child.Arrange(childRect);
            }

            var radius = CornerRadius;

            useComplexRender        = !CornerRadiusUtil.IsUniform(radius) || !ThicknessUtil.IsUniform(borders);
            backgroundGeometryCache = upperLeftCache = upperRightCache = lowerRightCache = lowerLeftCache = null;

            if (useComplexRender)
            {
                //  calculate border / background rendering geometry
                if (!DoubleUtil.IsZero(boundRect.Width) && !DoubleUtil.IsZero(boundRect.Height))
                {
                    var outerRadii = new Radii(boundRect, radius, borders, true);

                    // Upper-right corner
                    var radiusX = boundRect.TopRight.X - outerRadii.TopRight.X;
                    var radiusY = outerRadii.RightTop.Y - boundRect.TopRight.Y;
                    if (!DoubleUtil.IsZero(radiusX) || !DoubleUtil.IsZero(radiusY))
                    {
                        upperRightCache = GenerateRoundedGeometry(outerRadii.TopRight, outerRadii.RightTop, new Size(radiusX, radiusY));
                    }

                    // Lower-right corner
                    radiusX = boundRect.BottomRight.X - outerRadii.BottomRight.X;
                    radiusY = boundRect.BottomRight.Y - outerRadii.RightBottom.Y;
                    if (!DoubleUtil.IsZero(radiusX) || !DoubleUtil.IsZero(radiusY))
                    {
                        lowerRightCache = GenerateRoundedGeometry(outerRadii.RightBottom, outerRadii.BottomRight, new Size(radiusX, radiusY));
                    }

                    // Lower-left corner
                    radiusX = outerRadii.BottomLeft.X - boundRect.BottomLeft.X;
                    radiusY = boundRect.BottomLeft.Y - outerRadii.LeftBottom.Y;
                    if (!DoubleUtil.IsZero(radiusX) || !DoubleUtil.IsZero(radiusY))
                    {
                        lowerLeftCache = GenerateRoundedGeometry(outerRadii.BottomLeft, outerRadii.LeftBottom, new Size(radiusX, radiusY));
                    }

                    // Upper-left corner
                    radiusX = outerRadii.TopLeft.X - boundRect.TopLeft.X;
                    radiusY = outerRadii.LeftTop.Y - boundRect.TopLeft.Y;
                    if (!DoubleUtil.IsZero(radiusX) || !DoubleUtil.IsZero(radiusY))
                    {
                        upperLeftCache = GenerateRoundedGeometry(outerRadii.LeftTop, outerRadii.TopLeft, new Size(radiusX, radiusY));
                    }
                }

                if (!DoubleUtil.IsZero(innerRect.Width) && !DoubleUtil.IsZero(innerRect.Height))
                {
                    var innerRadii         = new Radii(innerRect, radius, borders, false);
                    var backgroundGeometry = new StreamGeometry();

                    using (StreamGeometryContext sc = backgroundGeometry.Open())
                    {
                        //  create the border geometry
                        sc.BeginFigure(innerRadii.TopLeft, true /* is filled */, true /* is closed */);

                        // Top line
                        sc.LineTo(innerRadii.TopRight, true /* is stroked */, false /* is smooth join */);

                        // Upper-right corners
                        var radiusX = innerRect.TopRight.X - innerRadii.TopRight.X;
                        var radiusY = innerRadii.RightTop.Y - innerRect.TopRight.Y;
                        if (!DoubleUtil.IsZero(radiusX) || !DoubleUtil.IsZero(radiusY))
                        {
                            sc.ArcTo(innerRadii.RightTop, new Size(radiusX, radiusY), 0, false, SweepDirection.Clockwise, true, false);
                        }

                        // Right line
                        sc.LineTo(innerRadii.RightBottom, true /* is stroked */, false /* is smooth join */);

                        // Lower-right corners
                        radiusX = innerRect.BottomRight.X - innerRadii.BottomRight.X;
                        radiusY = innerRect.BottomRight.Y - innerRadii.RightBottom.Y;
                        if (!DoubleUtil.IsZero(radiusX) || !DoubleUtil.IsZero(radiusY))
                        {
                            sc.ArcTo(innerRadii.BottomRight, new Size(radiusX, radiusY), 0, false, SweepDirection.Clockwise, true, false);
                        }

                        // Bottom line
                        sc.LineTo(innerRadii.BottomLeft, true /* is stroked */, false /* is smooth join */);

                        // Lower-left corners
                        radiusX = innerRadii.BottomLeft.X - innerRect.BottomLeft.X;
                        radiusY = innerRect.BottomLeft.Y - innerRadii.LeftBottom.Y;
                        if (!DoubleUtil.IsZero(radiusX) || !DoubleUtil.IsZero(radiusY))
                        {
                            sc.ArcTo(innerRadii.LeftBottom, new Size(radiusX, radiusY), 0, false, SweepDirection.Clockwise, true, false);
                        }

                        // Left line
                        sc.LineTo(innerRadii.LeftTop, true /* is stroked */, false /* is smooth join */);

                        // Upper-left corners
                        radiusX = innerRadii.TopLeft.X - innerRect.TopLeft.X;
                        radiusY = innerRadii.LeftTop.Y - innerRect.TopLeft.Y;
                        if (!DoubleUtil.IsZero(radiusX) || !DoubleUtil.IsZero(radiusY))
                        {
                            sc.ArcTo(innerRadii.TopLeft, new Size(radiusX, radiusY), 0, false, SweepDirection.Clockwise, true, false);
                        }
                    }

                    backgroundGeometry.Freeze();
                    backgroundGeometryCache = backgroundGeometry;
                }
            }

            return(finalSize);
        }