Пример #1
0
 public static Rect getMinMaxRect(float fontSize, float ascent, float descent)
 {
     return(Rect.fromLTWH((advanceFactor - sizeFactor) / 2 * fontSize,
                          descent - fontSize * sizeFactor,
                          fontSize * sizeFactor,
                          fontSize * sizeFactor));
 }
Пример #2
0
        public override void paint(Canvas canvas, Size size)
        {
            Paint paint = new Paint();

            paint.color = this.color;
            float radius = size.width / 2.0f;

            canvas.drawCircle(new Offset(radius, radius), radius, paint);
            canvas.drawRect(Rect.fromLTWH(0.0f, 0.0f, radius, radius), paint);
        }
Пример #3
0
        public override void paint(PaintingContext context, Offset offset)
        {
            if (this._texture == null)
            {
                return;
            }

            context.addLayer(new TextureLayer(
                                 rect: Rect.fromLTWH(offset.dx, offset.dy, this.size.width, this.size.height),
                                 texture: this._texture
                                 ));
        }
Пример #4
0
        public override void paint(PaintingContext context, Offset offset)
        {
            if (_textureId == null)
            {
                return;
            }

            context.addLayer(new TextureLayer(
                                 rect: Rect.fromLTWH(offset.dx, offset.dy, size.width, size.height),
                                 textureId: _textureId.Value
                                 ));
        }
Пример #5
0
        public Rect inscribe(Size size, Rect rect)
        {
            float halfWidthDelta  = (rect.width - size.width) / 2.0f;
            float halfHeightDelta = (rect.height - size.height) / 2.0f;

            return(Rect.fromLTWH(
                       rect.left + halfWidthDelta + x * halfWidthDelta,
                       rect.top + halfHeightDelta + y * halfHeightDelta,
                       size.width,
                       size.height
                       ));
        }
Пример #6
0
        void _drawImage(Image image, Offset offset, Paint paint)
        {
            D.assert(image != null);
            D.assert(offset != null);
            D.assert(paint != null);

            this._drawImageRect(image,
                                null,
                                Rect.fromLTWH(
                                    offset.dx, offset.dy,
                                    image.width / this._devicePixelRatio,
                                    image.height / this._devicePixelRatio),
                                paint);
        }
        public override void paint(Canvas canvas, Size size)
        {
            Paint paint = new Paint();

            paint.color = color;
            float radius = size.width / 2.0f;
            Rect  circle = Rect.fromCircle(center: new Offset(radius, radius), radius: radius);
            Rect  point  = Rect.fromLTWH(0.0f, 0.0f, radius, radius);
            Path  path   = new Path();

            path.addOval(circle);
            path.addRect(point);
            canvas.drawPath(path, paint);
        }
Пример #8
0
        public override void paint(PaintingContext context, Offset offset)
        {
            if (this._overflow <= 0.0f)
            {
                this.defaultPaint(context, offset);
                return;
            }

            if (this.size.isEmpty)
            {
                return;
            }

            context.pushClipRect(this.needsCompositing, offset, Offset.zero & this.size, this.defaultPaint);

            D.assert(() => {
                string debugOverflowHints =
                    $"The overflowing {this.GetType()} has an orientation of {this._direction}.\n" +
                    $"The edge of the {this.GetType()} that is overflowing has been marked " +
                    "in the rendering with a yellow and black striped pattern. This is " +
                    $"usually caused by the contents being too big for the {this.GetType()}. " +
                    "Consider applying a flex factor (e.g. using an Expanded widget) to " +
                    $"force the children of the {this.GetType()} to fit within the available " +
                    "space instead of being sized to their natural size.\n" +
                    "This is considered an error condition because it indicates that there " +
                    "is content that cannot be seen. If the content is legitimately bigger " +
                    "than the available space, consider clipping it with a ClipRect widget " +
                    "before putting it in the flex, or using a scrollable container rather " +
                    "than a Flex, like a ListView.";

                Rect overflowChildRect;
                switch (this._direction)
                {
                case Axis.horizontal:
                    overflowChildRect = Rect.fromLTWH(0.0f, 0.0f, this.size.width + this._overflow, 0.0f);
                    break;

                case Axis.vertical:
                    overflowChildRect = Rect.fromLTWH(0.0f, 0.0f, 0.0f, this.size.height + this._overflow);
                    break;

                default:
                    throw new Exception("Unknown direction: " + this._direction);
                }

                DebugOverflowIndicatorMixin.paintOverflowIndicator(this, context, offset, Offset.zero & this.size,
                                                                   overflowChildRect, overflowHints: debugOverflowHints);
                return(true);
            });
        }
Пример #9
0
        public static Rect getUVRect(int code)
        {
            bool exist = emojiLookupTable.TryGetValue(code, out int index);

            if (exist)
            {
                return(Rect.fromLTWH(
                           (index % colCount) * (1.0f / colCount),
                           (rowCount - 1 - (index / colCount)) * (1.0f / rowCount),
                           1.0f / colCount, 1.0f / rowCount));
            }

            Debug.LogWarning($"Unrecognized unicode for emoji {code:x}");
            return(Rect.fromLTWH(0, 0, 0, 0));
        }
Пример #10
0
        public void visualize(Canvas canvas, Rect rect) {
            Paint paint = new Paint {color = Colors.blue};
            Paint paint2 = new Paint {color = Colors.red};
            Paint paint3 = new Paint {color = Colors.green};
            Paint paint4 = new Paint {color = Colors.white70};

            float[] costFrames = this._laps;
            int curFrame = (this._currentSample - 1) % InstrumentationUtils.kMaxSamples;

            float barWidth = Mathf.Max(1, rect.width / costFrames.Length);
            float perHeight = rect.height / 32.0f;

            canvas.drawRect(rect, paint4);
            canvas.drawRect(Rect.fromLTWH(rect.left, rect.top + perHeight * 16.0f, rect.width, 1), paint3);

            float cur_x = rect.left;
            Path barPath = new Path();

            for (var i = 0; i < costFrames.Length; i++) {
                if (costFrames[i] != 0) {
                    float curHeight = Mathf.Min(perHeight * costFrames[i] * 1000, rect.height);
                    Rect barRect = Rect.fromLTWH(cur_x, rect.top + rect.height - curHeight, barWidth, curHeight);
                    barPath.addRect(barRect);
                }

                cur_x += barWidth;
            }

            canvas.drawPath(barPath, paint);
            if (curFrame >= 0 && curFrame < costFrames.Length) {
                if (costFrames[curFrame] != 0) {
                    float curHeight = Mathf.Min(perHeight * costFrames[curFrame] * 1000, rect.height);
                    Rect barRect = Rect.fromLTWH(rect.left + barWidth * curFrame, rect.top + rect.height - curHeight,
                        barWidth, curHeight);
                    canvas.drawRect(barRect, paint2);
                }

                var pb = new ParagraphBuilder(new ParagraphStyle { });
                pb.addText("Current Frame Cost: " + costFrames[curFrame] * 1000 + "ms" + " ; Max(in last 120 frames): " + this.maxDelta() * 1000 + "ms");
                var paragraph = pb.build();
                paragraph.layout(new ParagraphConstraints(width: 800));

                canvas.drawParagraph(paragraph, new Offset(rect.left, rect.top + rect.height - 12));
            }
        }
Пример #11
0
        protected override void performLayout()
        {
            this._layoutText(this.constraints.maxWidth);
            this._caretPrototype = Rect.fromLTWH(0.0f, _kCaretHeightOffset, _kCaretWidth,
                                                 this.preferredLineHeight - 2.0f * _kCaretHeightOffset);
            this._selectionRects = null;

            var textPainterSize = this._textPainter.size;

            this.size = new Size(this.constraints.maxWidth,
                                 this.constraints.constrainHeight(this._preferredHeight(this.constraints.maxWidth)));
            var contentSize = new Size(textPainterSize.width + _kCaretGap + _kCaretWidth,
                                       textPainterSize.height);
            var _maxScrollExtent = this._getMaxScrollExtend(contentSize);

            this._hasVisualOverflow = _maxScrollExtent > 0.0;
            this.offset.applyViewportDimension(this._viewportExtend);
            this.offset.applyContentDimensions(0.0f, _maxScrollExtent);
        }
Пример #12
0
        public override Rect getPreferredRect(
            RenderBox parentBox         = null,
            Offset offset               = null,
            SliderThemeData sliderTheme = null,
            bool?isEnabled              = null,
            bool?isDiscrete             = null)
        {
            float overlayWidth = sliderTheme.overlayShape.getPreferredSize(isEnabled, isDiscrete).width;
            float trackHeight  = sliderTheme.trackHeight;

            D.assert(overlayWidth >= 0);
            D.assert(trackHeight >= 0);
            D.assert(parentBox.size.width >= overlayWidth);
            D.assert(parentBox.size.height >= trackHeight);

            float trackLeft  = offset.dx + overlayWidth / 2f;
            float trackTop   = offset.dy + (parentBox.size.height - trackHeight) / 2f;
            float trackWidth = parentBox.size.width - overlayWidth;

            return(Rect.fromLTWH(trackLeft, trackTop, trackWidth, trackHeight));
        }
 public override void paint(Canvas canvas, Size size)
 {
     foreach (_Circle circle in this.circles)
     {
         Paint paint = new Paint();
         paint.color = circle.color;
         Rect rect = Rect.fromLTWH(0.0f, 0.0f, size.width, size.height);
         canvas.clipRect(rect);
         float      leftFraction = circle.horizontalLeadingOffset;
         Offset     center       = new Offset(leftFraction * size.width, size.height / 2.0f);
         FloatTween radiusTween  = new FloatTween(
             begin: 0.0f,
             end: _maxRadius(center, size)
             );
         canvas.drawCircle(
             center,
             radiusTween.evaluate(circle.animation),
             paint
             );
     }
 }
Пример #14
0
        public override void paint(Canvas canvas, Size size)
        {
            var paint = new Paint();

            paint.style = PaintingStyle.fill;
            var chart = this.animation.value;

            foreach (var bar in chart.bars)
            {
                paint.color = bar.color;
                canvas.drawRect(
                    Rect.fromLTWH(
                        bar.x,
                        size.height - bar.height,
                        bar.width,
                        bar.height
                        ),
                    paint
                    );
            }
        }
Пример #15
0
        void _reset()
        {
            foreach (var layer in this._layers)
            {
                this._clearLayer(layer);
            }

            RenderLayer firstLayer;

            if (this._layers.Count == 0)
            {
                var width  = this._renderTexture.width;
                var height = this._renderTexture.height;

                var bounds = Rect.fromLTWH(0, 0,
                                           width * this._fringeWidth,
                                           height * this._fringeWidth);

                firstLayer = new RenderLayer {
                    width       = width,
                    height      = height,
                    layerBounds = bounds,
                };
            }
            else
            {
                D.assert(this._layers.Count > 0);
                firstLayer = this._layers[0];
                firstLayer = new RenderLayer {
                    width       = firstLayer.width,
                    height      = firstLayer.height,
                    layerBounds = firstLayer.layerBounds,
                };
            }

            this._layers.Clear();
            this._layers.Add(firstLayer);
            this._currentLayer = firstLayer;
        }
        public void paint(Canvas canvas, Size size)
        {
            if (_glowOpacity.value == 0.0f)
            {
                return;
            }

            float  baseGlowScale = size.width > size.height ? size.height / size.width : 1.0f;
            float  radius        = size.width * 3.0f / 2.0f;
            float  height        = Mathf.Min(size.height, size.width * _widthToHeightFactor);
            float  scaleY        = _glowSize.value * baseGlowScale;
            Rect   rect          = Rect.fromLTWH(0.0f, 0.0f, size.width, height);
            Offset center        = new Offset((size.width / 2.0f) * (0.5f + _displacement), height - radius);
            Paint  paint         = new Paint();

            paint.color = color.withOpacity(_glowOpacity.value);
            canvas.save();
            canvas.scale(1.0f, scaleY);
            canvas.clipRect(rect);
            canvas.drawCircle(center, radius, paint);
            canvas.restore();
        }
Пример #17
0
        public void reset()
        {
            foreach (var layer in this._layers)
            {
                this._clearLayer(layer);
            }

            this._saveCount = 0;

            RenderLayer firstLayer;

            if (this._layers.Count == 0)
            {
                var bounds = Rect.fromLTWH(0, 0,
                                           this._renderTexture.width / this._devicePixelRatio,
                                           this._renderTexture.height / this._devicePixelRatio);
                firstLayer = new RenderLayer {
                    width       = this._renderTexture.width,
                    height      = this._renderTexture.height,
                    layerBounds = bounds,
                };
            }
            else
            {
                D.assert(this._layers.Count > 0);
                firstLayer = this._layers[0];
                firstLayer = new RenderLayer {
                    width       = firstLayer.width,
                    height      = firstLayer.height,
                    layerBounds = firstLayer.layerBounds,
                };
            }

            this._layers.Clear();
            this._layers.Add(firstLayer);
        }
Пример #18
0
        public override Widget build(BuildContext context)
        {
            LayerLink layerLink          = null;
            TextSelectionHandleType type = TextSelectionHandleType.left;

            switch (widget.position)
            {
            case _TextSelectionHandlePosition.start:
                layerLink = widget.startHandleLayerLink;
                type      = _chooseType(
                    widget.renderObject.textDirection,
                    TextSelectionHandleType.left,
                    TextSelectionHandleType.right
                    );
                break;

            case _TextSelectionHandlePosition.end:
                D.assert(!widget.selection.isCollapsed);
                layerLink = widget.endHandleLayerLink;
                type      = _chooseType(
                    widget.renderObject.textDirection,
                    TextSelectionHandleType.right,
                    TextSelectionHandleType.left
                    );
                break;
            }

            Offset handleAnchor = widget.selectionControls.getHandleAnchor(
                type,
                widget.renderObject.preferredLineHeight
                );
            Size handleSize = widget.selectionControls.getHandleSize(
                widget.renderObject.preferredLineHeight
                );

            Rect handleRect = Rect.fromLTWH(
                -handleAnchor.dx,
                -handleAnchor.dy,
                handleSize.width,
                handleSize.height
                );

            Rect interactiveRect = handleRect.expandToInclude(
                Rect.fromCircle(center: handleRect.center, radius: kMinInteractiveDimension / 2)
                );
            RelativeRect padding = RelativeRect.fromLTRB(
                Mathf.Max((interactiveRect.width - handleRect.width) / 2, 0),
                Mathf.Max((interactiveRect.height - handleRect.height) / 2, 0),
                Mathf.Max((interactiveRect.width - handleRect.width) / 2, 0),
                Mathf.Max((interactiveRect.height - handleRect.height) / 2, 0)
                );

            return(new CompositedTransformFollower(
                       link: layerLink,
                       offset: interactiveRect.topLeft,
                       showWhenUnlinked: false,
                       child: new FadeTransition(
                           opacity: _opacity,
                           child: new Container(
                               alignment: Alignment.topLeft,
                               width: interactiveRect.width,
                               height: interactiveRect.height,
                               child: new GestureDetector(
                                   behavior: HitTestBehavior.translucent,
                                   dragStartBehavior: widget.dragStartBehavior,
                                   onPanStart: _handleDragStart,
                                   onPanUpdate: _handleDragUpdate,
                                   onTap: _handleTap,
                                   child: new Padding(
                                       padding: EdgeInsets.only(
                                           left: padding.left,
                                           top: padding.top,
                                           right: padding.right,
                                           bottom: padding.bottom
                                           ),
                                       child: widget.selectionControls.buildHandle(context, type,
                                                                                   widget.renderObject.preferredLineHeight)
                                       )
                                   )
                               )
                           )
                       ));
        }
Пример #19
0
 public override void preroll(PrerollContext context, Matrix3 matrix)
 {
     this.paintBounds = Rect.fromLTWH(
         this._offset.dx, this._offset.dy, this._size.width, this._size.height);
 }
Пример #20
0
        private void paintImageSpan(PaintingContext context, Offset offset)
        {
            var canvas = context.canvas;
            var bounds = offset & size;

            canvas.save();
            var textOffset = 0;

            foreach (var span in text.children)
            {
                if (span is ImageSpan imageSpan)
                {
                    var offsetForCaret = getOffsetForCaret(
                        new TextPosition(offset: textOffset),
                        bounds
                        );
                    if (textOffset != 0 &&
                        offsetForCaret.dx == 0F &&
                        offsetForCaret.dy == 0F)
                    {
                        return;
                    }

                    var topLeftOffset = new Offset(
                        offset.dx + offsetForCaret.dx - (textOffset == 0 ? 0 : 0),
                        offset.dy + offsetForCaret.dy
                        );
                    if (imageSpan.imageResolver.image == null)
                    {
                        canvas.drawRect(
                            rect: Rect.fromLTWH(
                                topLeftOffset.dx + imageSpan.margin.left,
                                topLeftOffset.dy + imageSpan.margin.top,
                                imageSpan.innerWidth,
                                imageSpan.innerHeight
                                ),
                            paint: ImagePlaceholderBackgroundPaint);
                        var textBlobBuilder = new TextBlobBuilder();
                        var text            = $"{(char) Icons.MaterialImage.codePoint}";
                        var iconSize        = imageSpan.innerWidth > imageSpan.innerHeight * 3
                            ? imageSpan.innerHeight * 3 / 4
                            : imageSpan.innerWidth / 4;
                        textBlobBuilder.allocRunPos(
                            style: new TextStyle(
                                fontFamily: Icons.MaterialImage.fontFamily,
                                fontSize: iconSize
                                ),
                            text: text,
                            offset: 0,
                            size: text.Length);
                        var rect = topLeftOffset & new Size(imageSpan.innerWidth, imageSpan.innerHeight);
                        textBlobBuilder.setBounds(rect.toRect());
                        canvas.drawTextBlob(
                            textBlobBuilder.make(),
                            new Offset(
                                rect.left + (rect.width - iconSize) / 2,
                                rect.top + (rect.height + iconSize) / 2),
                            ImagePlaceholderPaint);

                        imageSpan.imageResolver.Resolve((imageInfo, synchronousCall) =>
                        {
                            if (synchronousCall)
                            {
                                ImageUtils.paintImage(
                                    canvas: canvas,
                                    rect: topLeftOffset & new Size(imageSpan.width, imageSpan.height),
                                    image: imageSpan.imageResolver.image,
                                    fit: BoxFit.scaleDown,
                                    alignment: Alignment.center
                                    );
                            }
                            else
                            {
                                if (owner == null || !owner.debugDoingPaint)
                                {
                                    markNeedsPaint();
                                }
                            }
                        });
                        textOffset += imageSpan.toPlainText().Length;

                        continue;
                    }

                    ImageUtils.paintImage(
                        canvas: canvas,
                        rect: Rect.fromLTWH(
                            topLeftOffset.dx + imageSpan.margin.left,
                            topLeftOffset.dy + imageSpan.margin.top,
                            imageSpan.innerWidth,
                            imageSpan.innerHeight
                            ),
                        image: imageSpan.imageResolver.image,
                        fit: BoxFit.scaleDown,
                        alignment: Alignment.center
                        );
                }

                textOffset += span.toPlainText().Length;
            }

            canvas.restore();
        }
Пример #21
0
 public static Rect getMinMaxRect(float fontSize, float ascent, float descent)
 {
     return(Rect.fromLTWH(fontSize * 0.05f, descent - fontSize, fontSize * 0.9f, fontSize * 0.9f));
 }
Пример #22
0
 public Rect getBounds()
 {
     return(Rect.fromLTWH(this._bounds.x, this._bounds.y, this._bounds.width, this._bounds.height));
 }
Пример #23
0
        Path _gapBorderPath(Canvas canvas, RRect center, float start, float extent)
        {
            Rect tlCorner = Rect.fromLTWH(
                center.left,
                center.top,
                center.tlRadiusX * 2.0f,
                center.tlRadiusY * 2.0f
                );
            Rect trCorner = Rect.fromLTWH(
                center.right - center.trRadiusX * 2.0f,
                center.top,
                center.trRadiusX * 2.0f,
                center.trRadiusY * 2.0f
                );
            Rect brCorner = Rect.fromLTWH(
                center.right - center.brRadiusX * 2.0f,
                center.bottom - center.brRadiusY * 2.0f,
                center.brRadiusX * 2.0f,
                center.brRadiusY * 2.0f
                );
            Rect blCorner = Rect.fromLTWH(
                center.left,
                center.bottom - center.brRadiusY * 2.0f,
                center.blRadiusX * 2.0f,
                center.blRadiusY * 2.0f
                );

            const float cornerArcSweep   = Mathf.PI / 2.0f;
            float       tlCornerArcSweep = start < center.tlRadiusX
                ? Mathf.Asin(start / center.tlRadiusX)
                : Mathf.PI / 2.0f;

            Path path = new Path();

            path.addArc(tlCorner, Mathf.PI, tlCornerArcSweep);
            path.moveTo(center.left + center.tlRadiusX, center.top);

            if (start > center.tlRadiusX)
            {
                path.lineTo(center.left + start, center.top);
            }

            const float trCornerArcStart = (3 * Mathf.PI) / 2.0f;
            const float trCornerArcSweep = cornerArcSweep;

            if (start + extent < center.width - center.trRadiusX)
            {
                path.relativeMoveTo(extent, 0.0f);
                path.lineTo(center.right - center.trRadiusX, center.top);
                path.addArc(trCorner, trCornerArcStart, trCornerArcSweep);
            }
            else if (start + extent < center.width)
            {
                float dx    = center.width - (start + extent);
                float sweep = Mathf.Acos(dx / center.trRadiusX);
                path.addArc(trCorner, trCornerArcStart + sweep, trCornerArcSweep - sweep);
            }

            path.moveTo(center.right, center.top + center.trRadiusY);
            path.lineTo(center.right, center.bottom - center.brRadiusY);
            path.addArc(brCorner, 0.0f, cornerArcSweep);
            path.lineTo(center.left + center.blRadiusX, center.bottom);
            path.addArc(blCorner, Mathf.PI / 2.0f, cornerArcSweep);
            path.lineTo(center.left, center.top + center.trRadiusY);
            return(path);
        }
        void _paintChildWithMagnifier(
            PaintingContext context,
            Offset offset,
            RenderBox child,
            // Matrix4x4 cylindricalTransform,
            Matrix3 cylindricalTransform,
            Offset offsetToCenter,
            Offset untransformedPaintingCoordinates
            )
        {
            float magnifierTopLinePosition    = this.size.height / 2 - this._itemExtent * this._magnification / 2;
            float magnifierBottomLinePosition = this.size.height / 2 + this._itemExtent * this._magnification / 2;

            bool isAfterMagnifierTopLine = untransformedPaintingCoordinates.dy
                                           >= magnifierTopLinePosition - this._itemExtent * this._magnification;
            bool isBeforeMagnifierBottomLine = untransformedPaintingCoordinates.dy
                                               <= magnifierBottomLinePosition;

            if (isAfterMagnifierTopLine && isBeforeMagnifierBottomLine)
            {
                Rect centerRect = Rect.fromLTWH(
                    0.0f,
                    magnifierTopLinePosition, this.size.width, this._itemExtent * this._magnification);
                Rect topHalfRect = Rect.fromLTWH(
                    0.0f,
                    0.0f, this.size.width,
                    magnifierTopLinePosition);
                Rect bottomHalfRect = Rect.fromLTWH(
                    0.0f,
                    magnifierBottomLinePosition, this.size.width,
                    magnifierTopLinePosition);

                context.pushClipRect(
                    false,
                    offset,
                    centerRect,
                    (PaintingContext context1, Offset offset1) => {
                    context1.pushTransform(
                        false,
                        offset1,
                        cylindricalTransform,
                        // this._centerOriginTransform(cylindricalTransform),
                        (PaintingContext context2, Offset offset2) => {
                        context2.paintChild(
                            child,
                            offset2 + untransformedPaintingCoordinates);
                    });
                });

                context.pushClipRect(
                    false,
                    offset,
                    untransformedPaintingCoordinates.dy <= magnifierTopLinePosition
                        ? topHalfRect
                        : bottomHalfRect,
                    (PaintingContext context1, Offset offset1) => {
                    this._paintChildCylindrically(
                        context1,
                        offset1,
                        child,
                        cylindricalTransform,
                        offsetToCenter
                        );
                }
                    );
            }
            else
            {
                this._paintChildCylindrically(
                    context,
                    offset,
                    child,
                    cylindricalTransform,
                    offsetToCenter
                    );
            }
        }
Пример #25
0
        public override void paint(PaintingContext context, Offset offset)
        {
            base.paint(context, offset);
            Offset      bottomRight = size.bottomRight(offset);
            Rect        outer       = Rect.fromLTRB(offset.dx, offset.dy, bottomRight.dx, bottomRight.dy);
            Rect        center      = outer.deflate(horizontalBorderSide.width / 2.0f);
            const float sweepAngle  = Mathf.PI / 2.0f;

            RRect rrect = RRect.fromRectAndCorners(
                center,
                topLeft: borderRadius.topLeft,
                topRight: borderRadius.topRight,
                bottomLeft: borderRadius.bottomLeft,
                bottomRight: borderRadius.bottomRight
                ).scaleRadii();

            Rect tlCorner = Rect.fromLTWH(
                rrect.left,
                rrect.top,
                rrect.tlRadiusX * 2.0f,
                rrect.tlRadiusY * 2.0f
                );
            Rect blCorner = Rect.fromLTWH(
                rrect.left,
                rrect.bottom - (rrect.blRadiusY * 2.0f),
                rrect.blRadiusX * 2.0f,
                rrect.blRadiusY * 2.0f
                );
            Rect trCorner = Rect.fromLTWH(
                rrect.right - (rrect.trRadiusX * 2.0f),
                rrect.top,
                rrect.trRadiusX * 2.0f,
                rrect.trRadiusY * 2.0f
                );
            Rect brCorner = Rect.fromLTWH(
                rrect.right - (rrect.brRadiusX * 2.0f),
                rrect.bottom - (rrect.brRadiusY * 2.0f),
                rrect.brRadiusX * 2.0f,
                rrect.brRadiusY * 2.0f
                );

            Paint leadingPaint = leadingBorderSide.toPaint();

            switch (textDirection)
            {
            case TextDirection.ltr: {
                if (isLastButton)
                {
                    Path leftPath = new Path();
                    leftPath.moveTo(rrect.left, rrect.bottom + leadingBorderSide.width / 2);
                    leftPath.lineTo(rrect.left, rrect.top - leadingBorderSide.width / 2);
                    context.canvas.drawPath(leftPath, leadingPaint);

                    Paint endingPaint = trailingBorderSide.toPaint();
                    Path  endingPath  = new Path();
                    endingPath.moveTo(rrect.left + horizontalBorderSide.width / 2.0f, rrect.top);
                    endingPath.lineTo(rrect.right - rrect.trRadiusX, rrect.top);
                    endingPath.addArc(trCorner, Mathf.PI * 3.0f / 2.0f, sweepAngle);
                    endingPath.lineTo(rrect.right, rrect.bottom - rrect.brRadiusY);
                    endingPath.addArc(brCorner, 0, sweepAngle);
                    endingPath.lineTo(rrect.left + horizontalBorderSide.width / 2.0f, rrect.bottom);
                    context.canvas.drawPath(endingPath, endingPaint);
                }
                else if (isFirstButton)
                {
                    Path leadingPath = new Path();
                    leadingPath.moveTo(outer.right, rrect.bottom);
                    leadingPath.lineTo(rrect.left + rrect.blRadiusX, rrect.bottom);
                    leadingPath.addArc(blCorner, Mathf.PI / 2.0f, sweepAngle);
                    leadingPath.lineTo(rrect.left, rrect.top + rrect.tlRadiusY);
                    leadingPath.addArc(tlCorner, Mathf.PI, sweepAngle);
                    leadingPath.lineTo(outer.right, rrect.top);
                    context.canvas.drawPath(leadingPath, leadingPaint);
                }
                else
                {
                    Path leadingPath = new Path();
                    leadingPath.moveTo(rrect.left, rrect.bottom + leadingBorderSide.width / 2);
                    leadingPath.lineTo(rrect.left, rrect.top - leadingBorderSide.width / 2);
                    context.canvas.drawPath(leadingPath, leadingPaint);

                    Paint horizontalPaint = horizontalBorderSide.toPaint();
                    Path  horizontalPaths = new Path();
                    horizontalPaths.moveTo(rrect.left + horizontalBorderSide.width / 2.0f, rrect.top);
                    horizontalPaths.lineTo(outer.right - rrect.trRadiusX, rrect.top);
                    horizontalPaths.moveTo(rrect.left + horizontalBorderSide.width / 2.0f + rrect.tlRadiusX,
                                           rrect.bottom);
                    horizontalPaths.lineTo(outer.right - rrect.trRadiusX, rrect.bottom);
                    context.canvas.drawPath(horizontalPaths, horizontalPaint);
                }

                break;
            }

            case TextDirection.rtl: {
                if (isLastButton)
                {
                    Path leadingPath = new Path();
                    leadingPath.moveTo(rrect.right, rrect.bottom + leadingBorderSide.width / 2);
                    leadingPath.lineTo(rrect.right, rrect.top - leadingBorderSide.width / 2);
                    context.canvas.drawPath(leadingPath, leadingPaint);

                    Paint endingPaint = trailingBorderSide.toPaint();
                    Path  endingPath  = new Path();
                    endingPath.moveTo(rrect.right - horizontalBorderSide.width / 2.0f, rrect.top);
                    endingPath.lineTo(rrect.left + rrect.tlRadiusX, rrect.top);
                    endingPath.addArc(tlCorner, Mathf.PI * 3.0f / 2.0f, -sweepAngle);
                    endingPath.lineTo(rrect.left, rrect.bottom - rrect.blRadiusY);
                    endingPath.addArc(blCorner, Mathf.PI, -sweepAngle);
                    endingPath.lineTo(rrect.right - horizontalBorderSide.width / 2.0f, rrect.bottom);
                    context.canvas.drawPath(endingPath, endingPaint);
                }
                else if (isFirstButton)
                {
                    Path leadingPath = new Path();
                    leadingPath.moveTo(outer.left, rrect.bottom);
                    leadingPath.lineTo(rrect.right - rrect.brRadiusX, rrect.bottom);
                    leadingPath.addArc(brCorner, Mathf.PI / 2.0f, -sweepAngle);
                    leadingPath.lineTo(rrect.right, rrect.top + rrect.trRadiusY);
                    leadingPath.addArc(trCorner, 0, -sweepAngle);
                    leadingPath.lineTo(outer.left, rrect.top);
                    context.canvas.drawPath(leadingPath, leadingPaint);
                }
                else
                {
                    Path leadingPath = new Path();
                    leadingPath.moveTo(rrect.right, rrect.bottom + leadingBorderSide.width / 2);
                    leadingPath.lineTo(rrect.right, rrect.top - leadingBorderSide.width / 2);
                    context.canvas.drawPath(leadingPath, leadingPaint);

                    Paint horizontalPaint = horizontalBorderSide.toPaint();
                    Path  horizontalPaths = new Path();
                    horizontalPaths.moveTo(rrect.right - horizontalBorderSide.width / 2.0f, rrect.top);
                    horizontalPaths.lineTo(outer.left - rrect.tlRadiusX, rrect.top);
                    horizontalPaths.moveTo(rrect.right - horizontalBorderSide.width / 2.0f + rrect.trRadiusX,
                                           rrect.bottom);
                    horizontalPaths.lineTo(outer.left - rrect.tlRadiusX, rrect.bottom);
                    context.canvas.drawPath(horizontalPaths, horizontalPaint);
                }

                break;
            }
            }
        }
Пример #26
0
 public static Rect operator &(Offset a, Size other)
 {
     return(Rect.fromLTWH(a.dx, a.dy, other.width, other.height));
 }
Пример #27
0
        public override void paint(PaintingContext context, Offset offset)
        {
            Canvas canvas = context.canvas;

            float currentValue         = this._position.value;
            float currentReactionValue = this._reaction.value;

            float visualPosition = 0f;

            switch (this.textDirection)
            {
            case TextDirection.rtl:
                visualPosition = 1.0f - currentValue;
                break;

            case TextDirection.ltr:
                visualPosition = currentValue;
                break;
            }

            Color trackColor      = this._value ? this.activeColor : CupertinoSwitchUtils._kTrackColor;
            float borderThickness =
                1.5f + (CupertinoSwitchUtils._kTrackRadius - 1.5f) * Mathf.Max(currentReactionValue, currentValue);

            Paint paint = new Paint();

            paint.color = trackColor;

            Rect trackRect = Rect.fromLTWH(
                offset.dx + (this.size.width - CupertinoSwitchUtils._kTrackWidth) / 2.0f,
                offset.dy + (this.size.height - CupertinoSwitchUtils._kTrackHeight) / 2.0f,
                CupertinoSwitchUtils._kTrackWidth,
                CupertinoSwitchUtils._kTrackHeight
                );
            RRect outerRRect = RRect.fromRectAndRadius(trackRect, Radius.circular(CupertinoSwitchUtils
                                                                                  ._kTrackRadius));
            RRect innerRRect = RRect.fromRectAndRadius(trackRect.deflate(borderThickness), Radius.circular
                                                           (CupertinoSwitchUtils._kTrackRadius));

            canvas.drawDRRect(outerRRect, innerRRect, paint);

            float currentThumbExtension = CupertinoThumbPainter.extension * currentReactionValue;
            float thumbLeft             = MathUtils.lerpFloat(
                trackRect.left + CupertinoSwitchUtils._kTrackInnerStart - CupertinoThumbPainter.radius,
                trackRect.left + CupertinoSwitchUtils._kTrackInnerEnd - CupertinoThumbPainter.radius -
                currentThumbExtension,
                visualPosition
                );
            float thumbRight = MathUtils.lerpFloat(
                trackRect.left + CupertinoSwitchUtils._kTrackInnerStart + CupertinoThumbPainter.radius +
                currentThumbExtension,
                trackRect.left + CupertinoSwitchUtils._kTrackInnerEnd + CupertinoThumbPainter.radius,
                visualPosition
                );
            float thumbCenterY = offset.dy + this.size.height / 2.0f;

            this._thumbPainter.paint(canvas, Rect.fromLTRB(
                                         thumbLeft,
                                         thumbCenterY - CupertinoThumbPainter.radius,
                                         thumbRight,
                                         thumbCenterY + CupertinoThumbPainter.radius
                                         ));
        }
        static List <_OverflowRegionData> _calculateOverflowRegions(RelativeRect overflow, Rect containerRect)
        {
            List <_OverflowRegionData> regions = new List <_OverflowRegionData> {
            };

            if (overflow.left > 0.0f)
            {
                Rect markerRect = Rect.fromLTWH(
                    0.0f,
                    0.0f,
                    containerRect.width * _indicatorFraction,
                    containerRect.height
                    );
                regions.Add(new _OverflowRegionData(
                                rect: markerRect,
                                label: "LEFT OVERFLOWED BY ${_formatPixels(overflow.left)} PIXELS",
                                labelOffset: markerRect.centerLeft +
                                new Offset(_indicatorFontSizePixels + _indicatorLabelPaddingPixels, 0.0f),
                                rotation: Mathf.PI / 2.0f,
                                side: _OverflowSide.left
                                ));
            }

            if (overflow.right > 0.0f)
            {
                Rect markerRect = Rect.fromLTWH(
                    containerRect.width * (1.0f - _indicatorFraction),
                    0.0f,
                    containerRect.width * _indicatorFraction,
                    containerRect.height
                    );
                regions.Add(new _OverflowRegionData(
                                rect: markerRect,
                                label: $"RIGHT OVERFLOWED BY {_formatPixels(overflow.right)} PIXELS",
                                labelOffset: markerRect.centerRight -
                                new Offset(_indicatorFontSizePixels + _indicatorLabelPaddingPixels, 0.0f),
                                rotation: -Mathf.PI / 2.0f,
                                side: _OverflowSide.right
                                ));
            }

            if (overflow.top > 0.0f)
            {
                Rect markerRect = Rect.fromLTWH(
                    0.0f,
                    0.0f,
                    containerRect.width,
                    containerRect.height * _indicatorFraction
                    );
                regions.Add(new _OverflowRegionData(
                                rect: markerRect,
                                label: $"TOP OVERFLOWED BY {_formatPixels(overflow.top)} PIXELS",
                                labelOffset: markerRect.topCenter + new Offset(0.0f, _indicatorLabelPaddingPixels),
                                rotation: 0.0f,
                                side: _OverflowSide.top
                                ));
            }

            if (overflow.bottom > 0.0f)
            {
                Rect markerRect = Rect.fromLTWH(
                    0.0f,
                    containerRect.height * (1.0f - _indicatorFraction),
                    containerRect.width,
                    containerRect.height * _indicatorFraction
                    );
                regions.Add(new _OverflowRegionData(
                                rect: markerRect,
                                label: $"BOTTOM OVERFLOWED BY {_formatPixels(overflow.bottom)} PIXELS",
                                labelOffset: markerRect.bottomCenter -
                                new Offset(0.0f, _indicatorFontSizePixels + _indicatorLabelPaddingPixels),
                                rotation: 0.0f,
                                side: _OverflowSide.bottom
                                ));
            }

            return(regions);
        }
Пример #29
0
        public void addDrawCmd(DrawCmd drawCmd)
        {
            this._drawCmds.Add(drawCmd);

            switch (drawCmd)
            {
            case DrawSave _:
                this._states.Add(this._getState().copy());
                break;

            case DrawSaveLayer cmd: {
                this._states.Add(new CanvasState {
                        xform       = Matrix3.I(),
                        scissor     = cmd.rect.shift(-cmd.rect.topLeft),
                        saveLayer   = true,
                        layerOffset = cmd.rect.topLeft,
                        paintBounds = Rect.zero,
                    });
                break;
            }

            case DrawRestore _: {
                var stateToRestore = this._getState();
                this._states.RemoveAt(this._states.Count - 1);
                var state = this._getState();

                if (!stateToRestore.saveLayer)
                {
                    state.paintBounds = stateToRestore.paintBounds;
                }
                else
                {
                    var paintBounds = stateToRestore.paintBounds.shift(stateToRestore.layerOffset);
                    paintBounds = state.xform.mapRect(paintBounds);
                    this._addPaintBounds(paintBounds);
                }
                break;
            }

            case DrawTranslate cmd: {
                var state = this._getState();
                state.xform = new Matrix3(state.xform);
                state.xform.preTranslate(cmd.dx, cmd.dy);
                break;
            }

            case DrawScale cmd: {
                var state = this._getState();
                state.xform = new Matrix3(state.xform);
                state.xform.preScale(cmd.sx, (cmd.sy ?? cmd.sx));
                break;
            }

            case DrawRotate cmd: {
                var state = this._getState();
                state.xform = new Matrix3(state.xform);
                if (cmd.offset == null)
                {
                    state.xform.preRotate(cmd.radians);
                }
                else
                {
                    state.xform.preRotate(cmd.radians,
                                          cmd.offset.dx,
                                          cmd.offset.dy);
                }
                break;
            }

            case DrawSkew cmd: {
                var state = this._getState();
                state.xform = new Matrix3(state.xform);
                state.xform.preSkew(cmd.sx, cmd.sy);
                break;
            }

            case DrawConcat cmd: {
                var state = this._getState();
                state.xform = new Matrix3(state.xform);
                state.xform.preConcat(cmd.matrix);
                break;
            }

            case DrawResetMatrix _: {
                var state = this._getState();
                state.xform = Matrix3.I();
                break;
            }

            case DrawSetMatrix cmd: {
                var state = this._getState();
                state.xform = new Matrix3(cmd.matrix);
                break;
            }

            case DrawClipRect cmd: {
                var state = this._getState();

                var rect = state.xform.mapRect(cmd.rect);
                state.scissor = state.scissor == null ? rect : state.scissor.intersect(rect);
                break;
            }

            case DrawClipRRect cmd: {
                var state = this._getState();

                var rect = state.xform.mapRect(cmd.rrect.outerRect);
                state.scissor = state.scissor == null ? rect : state.scissor.intersect(rect);
                break;
            }

            case DrawClipPath cmd: {
                var state = this._getState();
                var scale = XformUtils.getScale(state.xform);

                var rect = cmd.path.flatten(
                    scale * Window.instance.devicePixelRatio
                    ).getFillMesh(out _).transform(state.xform).bounds;
                state.scissor = state.scissor == null ? rect : state.scissor.intersect(rect);
                break;
            }

            case DrawPath cmd: {
                var state            = this._getState();
                var scale            = XformUtils.getScale(state.xform);
                var path             = cmd.path;
                var paint            = cmd.paint;
                var devicePixelRatio = Window.instance.devicePixelRatio;

                MeshMesh mesh;
                if (paint.style == PaintingStyle.fill)
                {
                    var cache = path.flatten(scale * devicePixelRatio);
                    mesh = cache.getFillMesh(out _).transform(state.xform);
                }
                else
                {
                    float strokeWidth = (paint.strokeWidth * scale).clamp(0, 200.0f);
                    float fringeWidth = 1 / devicePixelRatio;

                    if (strokeWidth < fringeWidth)
                    {
                        strokeWidth = fringeWidth;
                    }

                    var cache = path.flatten(scale * devicePixelRatio);
                    mesh = cache.getStrokeMesh(
                        strokeWidth / scale * 0.5f,
                        paint.strokeCap,
                        paint.strokeJoin,
                        paint.strokeMiterLimit).transform(state.xform);
                }

                if (paint.maskFilter != null && paint.maskFilter.sigma != 0)
                {
                    float sigma  = scale * paint.maskFilter.sigma;
                    float sigma3 = 3 * sigma;
                    this._addPaintBounds(mesh.bounds.inflate(sigma3));
                }
                else
                {
                    this._addPaintBounds(mesh.bounds);
                }
                break;
            }

            case DrawImage cmd: {
                var state = this._getState();
                var rect  = Rect.fromLTWH(cmd.offset.dx, cmd.offset.dy,
                                          cmd.image.width, cmd.image.height);
                rect = state.xform.mapRect(rect);
                this._addPaintBounds(rect);
                break;
            }

            case DrawImageRect cmd: {
                var state = this._getState();
                var rect  = state.xform.mapRect(cmd.dst);
                this._addPaintBounds(rect);
                break;
            }

            case DrawImageNine cmd: {
                var state = this._getState();
                var rect  = state.xform.mapRect(cmd.dst);
                this._addPaintBounds(rect);
                break;
            }

            case DrawPicture cmd: {
                var state = this._getState();
                var rect  = state.xform.mapRect(cmd.picture.paintBounds);
                this._addPaintBounds(rect);
                break;
            }

            case DrawTextBlob cmd: {
                var state = this._getState();
                var scale = XformUtils.getScale(state.xform);
                var rect  = cmd.textBlob.boundsInText.shift(cmd.offset);
                rect = state.xform.mapRect(rect);

                var paint = cmd.paint;
                if (paint.maskFilter != null && paint.maskFilter.sigma != 0)
                {
                    float sigma  = scale * paint.maskFilter.sigma;
                    float sigma3 = 3 * sigma;
                    this._addPaintBounds(rect.inflate(sigma3));
                }
                else
                {
                    this._addPaintBounds(rect);
                }

                break;
            }

            default:
                throw new Exception("unknown drawCmd: " + drawCmd);
            }
        }
Пример #30
0
        public override void paint(PaintingContext context, Offset offset)
        {
            D.assert(_children.Count == this.rows * this.columns);
            if (this.rows * this.columns == 0)
            {
                if (border != null)
                {
                    Rect borderRect = Rect.fromLTWH(offset.dx, offset.dy, size.width, 0.0f);
                    border.paint(context.canvas, borderRect, rows: new List <float>(), columns: new List <float>());
                }

                return;
            }

            D.assert(_rowTops.Count == this.rows + 1);
            if (_rowDecorations != null)
            {
                D.assert(_rowDecorations.Count == _rowDecorationPainters.Count);
                Canvas canvas = context.canvas;
                for (int y = 0; y < rows; y++)
                {
                    if (_rowDecorations.Count <= y)
                    {
                        break;
                    }

                    if (_rowDecorations[y] != null)
                    {
                        _rowDecorationPainters[y] = _rowDecorationPainters[y] ??
                                                    _rowDecorations[y].createBoxPainter(markNeedsPaint);
                        _rowDecorationPainters[y].paint(
                            canvas,
                            new Offset(offset.dx, offset.dy + _rowTops[y]),
                            configuration.copyWith(
                                size: new Size(size.width, _rowTops[y + 1] - _rowTops[y])
                                )
                            );
                    }
                }
            }

            for (int index = 0; index < _children.Count; index++)
            {
                RenderBox child = _children[index];
                if (child != null)
                {
                    BoxParentData childParentData = (BoxParentData)child.parentData;
                    context.paintChild(child, childParentData.offset + offset);
                }
            }

            D.assert(_rows == _rowTops.Count - 1);
            D.assert(_columns == _columnLefts.Count);
            if (border != null)
            {
                Rect borderRect = Rect.fromLTWH(offset.dx, offset.dy, size.width,
                                                _rowTops[_rowTops.Count - 1]);
                List <float> rows    = _rowTops.GetRange(1, _rowTops.Count - 2);
                List <float> columns = _columnLefts.GetRange(1, _columnLefts.Count - 1);
                border.paint(context.canvas, borderRect, rows: rows, columns: columns);
            }
        }