public void draw(Canvas canvas)
        {
            var boundRect = canvas.getTotalMatrix().mapRect(this.logicalRect);
            var bounds    = boundRect.withDevicePixelRatio(this.devicePixelRatio);

            D.assert(() => {
                var boundsInPixel = boundRect.roundOutScale(this.devicePixelRatio);
                var textureWidth  = Mathf.CeilToInt(boundsInPixel.width);
                var textureHeight = Mathf.CeilToInt(boundsInPixel.height);

                //it is possible that there is a minor difference between the bound size and the image size (1 pixel at
                //most) due to the roundOut operation when calculating the bounds if the elements in the canvas transform
                //is not all integer
                D.assert(Mathf.Abs(this.image.width - textureWidth) <= 1);
                D.assert(Mathf.Abs(this.image.height - textureHeight) <= 1);
                return(true);
            });

            canvas.save();
            try {
                canvas.resetMatrix();
                canvas.drawImage(this.image, bounds.topLeft, new Paint());
            }
            finally {
                canvas.restore();
            }
        }
        void _paintSide(Canvas canvas, Size size, _GlowController controller, AxisDirection axisDirection,
                        GrowthDirection growthDirection)
        {
            if (controller == null)
            {
                return;
            }

            switch (GrowthDirectionUtils.applyGrowthDirectionToAxisDirection(axisDirection, growthDirection))
            {
            case AxisDirection.up:
                controller.paint(canvas, size);
                break;

            case AxisDirection.down:
                canvas.save();
                canvas.translate(0.0f, size.height);
                canvas.scale(1.0f, -1.0f);
                controller.paint(canvas, size);
                canvas.restore();
                break;

            case AxisDirection.left:
                canvas.save();
                canvas.rotate(piOver2);
                canvas.scale(1.0f, -1.0f);
                controller.paint(canvas, new Size(size.height, size.width));
                canvas.restore();
                break;

            case AxisDirection.right:
                canvas.save();
                canvas.translate(size.width, 0.0f);
                canvas.rotate(piOver2);
                controller.paint(canvas, new Size(size.height, size.width));
                canvas.restore();
                break;
            }
        }
Пример #3
0
        protected override void paintFeature(Canvas canvas, Matrix4 transform)
        {
            Paint paint = new Paint {
                color = this.color.withAlpha(this._alpha.value)
            };
            Offset center = this._position;

            if (this._repositionToReferenceBox)
            {
                center = Offset.lerp(center, this.referenceBox.size.center(Offset.zero), this._radiusController.value);
            }

            Offset originOffset = transform.getAsTranslation();

            canvas.save();
            if (originOffset == null)
            {
                canvas.concat(transform.toMatrix3());
            }
            else
            {
                canvas.translate(originOffset.dx, originOffset.dy);
            }

            if (this._clipCallback != null)
            {
                Rect rect = this._clipCallback();
                if (this._customBorder != null)
                {
                    canvas.clipPath(this._customBorder.getOuterPath(rect));
                }
                else if (this._borderRadius != BorderRadius.zero)
                {
                    canvas.clipRRect(RRect.fromRectAndCorners(
                                         rect,
                                         topLeft: this._borderRadius.topLeft,
                                         topRight: this._borderRadius.topRight,
                                         bottomLeft: this._borderRadius.bottomLeft,
                                         bottomRight: this._borderRadius.bottomRight));
                }
                else
                {
                    canvas.clipRect(rect);
                }
            }

            canvas.drawCircle(center, this._radius.value, paint);
            canvas.restore();
        }
Пример #4
0
        public override void paint(Canvas canvas, Size size)
        {
            Paint paint = new Paint();

            canvas.save();
            canvas.translate(size.width / 2.0f, size.height / 2.0f);

            int activeTick = (CupertinoActivityIndicatorUtils._kTickCount * position.value).floor();

            for (int i = 0; i < CupertinoActivityIndicatorUtils._kTickCount; ++i)
            {
                int t = ((i + activeTick) % CupertinoActivityIndicatorUtils._kTickCount);
                paint.color = activeColor.withAlpha(CupertinoActivityIndicatorUtils._alphaValues[t]);
                canvas.drawRRect(tickFundamentalRRect, paint);
                canvas.rotate(-CupertinoActivityIndicatorUtils._kTwoPI / CupertinoActivityIndicatorUtils._kTickCount);
            }

            canvas.restore();
        }
Пример #5
0
        public void paint(Canvas canvas, Rect rect, Path clipPath, ImageConfiguration configuration)
        {
            D.assert(canvas != null);
            D.assert(rect != null);
            D.assert(configuration != null);

            ImageStream newImageStream = this._details.image.resolve(configuration);

            if (newImageStream.key != this._imageStream?.key)
            {
                this._imageStream?.removeListener(this._imageListener);
                this._imageStream = newImageStream;
                this._imageStream.addListener(this._imageListener);
            }

            if (this._image == null)
            {
                return;
            }

            if (clipPath != null)
            {
                canvas.save();
                canvas.clipPath(clipPath);
            }

            ImageUtils.paintImage(
                canvas: canvas,
                rect: rect,
                image: this._image.image,
                scale: this._image.scale,
                colorFilter: this._details.colorFilter,
                fit: this._details.fit,
                alignment: this._details.alignment,
                centerSlice: this._details.centerSlice,
                repeat: this._details.repeat
                );

            if (clipPath != null)
            {
                canvas.restore();
            }
        }
        public override void paint(Canvas canvas, Size size)
        {
            Paint paint = new Paint();

            canvas.save();
            canvas.translate(size.width / 2.0f, size.height / 2.0f);

            int activeTick = (CupertinoActivityIndicatorUtils._kTickCount * this.position.value).floor();

            for (int i = 0; i < CupertinoActivityIndicatorUtils._kTickCount; ++i)
            {
                float t = (((i + activeTick) % CupertinoActivityIndicatorUtils._kTickCount) /
                           CupertinoActivityIndicatorUtils._kHalfTickCount).clamp(0, 1);
                paint.color = Color.lerp(a: CupertinoActivityIndicatorUtils._kActiveTickColor,
                                         b: CupertinoActivityIndicatorUtils._kTickColor, t: t);
                canvas.drawRRect(rect: this.tickFundamentalRRect, paint: paint);
                canvas.rotate(-CupertinoActivityIndicatorUtils._kTwoPI / CupertinoActivityIndicatorUtils._kTickCount);
            }

            canvas.restore();
        }
        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();
        }
Пример #8
0
        public void draw(Canvas canvas)
        {
            var bounds = canvas.getTotalMatrix().mapRect(this.logicalRect).roundOut(this.devicePixelRatio);

            D.assert(() => {
                var textureWidth  = Mathf.CeilToInt(bounds.width * this.devicePixelRatio);
                var textureHeight = Mathf.CeilToInt(bounds.height * this.devicePixelRatio);

                D.assert(this.image.width == textureWidth);
                D.assert(this.image.height == textureHeight);
                return(true);
            });

            canvas.save();
            try {
                canvas.resetMatrix();
                canvas.drawImage(this.image, bounds.topLeft, new Paint());
            }
            finally {
                canvas.restore();
            }
        }
        public static void paintZigZag(Canvas canvas, Paint paint, Offset start, Offset end, int zigs, float width)
        {
            D.assert(MathUtils.isFinite(zigs));
            D.assert(zigs > 0);
            canvas.save();
            canvas.translate(start.dx, start.dy);
            end = end - start;
            canvas.rotate(Mathf.Atan2(end.dy, end.dx));
            float length  = end.distance;
            float spacing = length / (zigs * 2.0f);
            Path  path    = new Path();

            path.moveTo(0.0f, 0.0f);
            for (int index = 0; index < zigs; index += 1)
            {
                float x = (index * 2.0f + 1.0f) * spacing;
                float y = width * ((index % 2.0f) * 2.0f - 1.0f);
                path.lineTo(x, y);
            }

            path.lineTo(length, 0.0f);
            canvas.drawPath(path, paint);
            canvas.restore();
        }
Пример #10
0
        public override void paint(PaintContext context)
        {
            D.assert(this.needsPainting);
            const int padding   = 8;
            const int fpsHeight = 20;

            Canvas canvas = context.canvas;

            canvas.save();

            float x      = this.paintBounds.left + padding;
            float y      = this.paintBounds.top + padding;
            float width  = this.paintBounds.width - padding * 2;
            float height = this.paintBounds.height;

            this._drawFPS(canvas, x, y);

            if ((this._options & (int)PerformanceOverlayOption.drawFrameCost) == 1)
            {
                this._drawFrameCost(canvas, x, y + fpsHeight, width, height - padding - fpsHeight);
            }

            canvas.restore();
        }
Пример #11
0
        public static void paintImage(
            Canvas canvas               = null,
            Rect rect                   = null,
            Image image                 = null,
            float scale                 = 1.0f,
            ColorFilter colorFilter     = null,
            BoxFit?fit                  = null,
            Alignment alignment         = null,
            Rect centerSlice            = null,
            ImageRepeat repeat          = ImageRepeat.noRepeat,
            bool flipHorizontally       = false,
            bool invertColors           = false,
            FilterQuality filterQuality = FilterQuality.low
            )
        {
            D.assert(canvas != null);
            D.assert(rect != null);
            D.assert(image != null);
            alignment = alignment ?? Alignment.center;

            if (rect.isEmpty)
            {
                return;
            }

            Size   outputSize  = rect.size;
            Size   inputSize   = new Size(image.width, image.height);
            Offset sliceBorder = null;

            if (centerSlice != null)
            {
                sliceBorder = new Offset(
                    centerSlice.left + inputSize.width - centerSlice.right,
                    centerSlice.top + inputSize.height - centerSlice.bottom
                    );
                outputSize -= sliceBorder;
                inputSize  -= sliceBorder;
            }

            fit = fit ?? (centerSlice == null ? BoxFit.scaleDown : BoxFit.fill);
            D.assert(centerSlice == null || (fit != BoxFit.none && fit != BoxFit.cover),
                     () => $"centerSlice was used with a BoxFit {fit} that is not supported.");
            FittedSizes fittedSizes     = FittedSizes.applyBoxFit(fit.Value, inputSize / scale, outputSize);
            Size        sourceSize      = fittedSizes.source * scale;
            Size        destinationSize = fittedSizes.destination;

            if (centerSlice != null)
            {
                outputSize      += sliceBorder;
                destinationSize += sliceBorder;
                D.assert(sourceSize == inputSize,
                         () =>
                         $"centerSlice was used with a BoxFit {fit} that does not guarantee that the image is fully visible.");
            }

            if (repeat != ImageRepeat.noRepeat && destinationSize == outputSize)
            {
                repeat = ImageRepeat.noRepeat;
            }

            Paint paint = new Paint();

            if (colorFilter != null)
            {
                paint.colorFilter = colorFilter;
            }

            if (sourceSize != destinationSize)
            {
                paint.filterQuality = filterQuality;
            }

            paint.invertColors = invertColors;

            float  halfWidthDelta  = (outputSize.width - destinationSize.width) / 2.0f;
            float  halfHeightDelta = (outputSize.height - destinationSize.height) / 2.0f;
            float  dx = halfWidthDelta + (flipHorizontally ? -alignment.x : alignment.x) * halfWidthDelta;
            float  dy = halfHeightDelta + alignment.y * halfHeightDelta;
            Offset destinationPosition = rect.topLeft.translate(dx, dy);
            Rect   destinationRect     = destinationPosition & destinationSize;
            bool   needSave            = repeat != ImageRepeat.noRepeat || flipHorizontally;

            if (needSave)
            {
                canvas.save();
            }

            if (flipHorizontally)
            {
                float dxInside = -(rect.left + rect.width / 2.0f);
                canvas.translate(-dxInside, 0.0f);
                canvas.scale(-1.0f, 1.0f);
                canvas.translate(dxInside, 0.0f);
            }

            if (repeat != ImageRepeat.noRepeat)
            {
                canvas.clipRect(rect);
            }

            if (centerSlice == null)
            {
                Rect sourceRect = alignment.inscribe(
                    sourceSize, Offset.zero & inputSize
                    );
                if (repeat == ImageRepeat.noRepeat)
                {
                    canvas.drawImageRect(image, sourceRect, destinationRect, paint);
                }
                else
                {
                    foreach (Rect tileRect in _generateImageTileRects(rect, destinationRect, repeat))
                    {
                        canvas.drawImageRect(image, sourceRect, tileRect, paint);
                    }
                }
            }
            else
            {
                if (repeat == ImageRepeat.noRepeat)
                {
                    canvas.drawImageNine(image, centerSlice, destinationRect, paint);
                }
                else
                {
                    foreach (Rect tileRect in _generateImageTileRects(rect, destinationRect, repeat))
                    {
                        canvas.drawImageNine(image, centerSlice, tileRect, paint);
                    }
                }
            }

            if (needSave)
            {
                canvas.restore();
            }
        }
Пример #12
0
        public void paint(Canvas canvas, Rect rect, Path clipPath, ImageConfiguration configuration)
        {
            D.assert(canvas != null);
            D.assert(rect != null);
            D.assert(configuration != null);

            bool flipHorizontally = false;

            if (_details.matchTextDirection)
            {
                D.assert(() => {
                    // We check this first so that the assert will fire immediately, not just
                    // when the image is ready.
                    if (configuration.textDirection == null)
                    {
                        throw new UIWidgetsError(new List <DiagnosticsNode>()
                        {
                            new ErrorSummary(
                                "DecorationImage.matchTextDirection can only be used when a TextDirection is available."),
                            new ErrorDescription(
                                "When DecorationImagePainter.paint() was called, there was no text direction provided " +
                                "in the ImageConfiguration object to match."
                                ),
                            new DiagnosticsProperty <DecorationImage>("The DecorationImage was", _details,
                                                                      style: DiagnosticsTreeStyle.errorProperty),
                            new DiagnosticsProperty <ImageConfiguration>("The ImageConfiguration was", configuration,
                                                                         style: DiagnosticsTreeStyle.errorProperty)
                        });
                    }

                    return(true);
                });
                if (configuration.textDirection == TextDirection.rtl)
                {
                    flipHorizontally = true;
                }
            }

            ImageStream newImageStream = _details.image.resolve(configuration);

            if (newImageStream.key != _imageStream?.key)
            {
                ImageStreamListener listener = new ImageStreamListener(
                    _handleImage,
                    onError: _details.onError
                    );
                _imageStream?.removeListener(listener);
                _imageStream = newImageStream;
                _imageStream.addListener(listener);
            }

            if (_image == null)
            {
                return;
            }

            if (clipPath != null)
            {
                canvas.save();
                canvas.clipPath(clipPath);
            }

            painting_.paintImage(
                canvas: canvas,
                rect: rect,
                image: _image.image,
                scale: _image.scale,
                colorFilter: _details.colorFilter,
                fit: _details.fit,
                alignment: _details.alignment.resolve(configuration.textDirection),
                centerSlice: _details.centerSlice,
                repeat: _details.repeat,
                flipHorizontally: flipHorizontally,
                filterQuality: FilterQuality.low
                );

            if (clipPath != null)
            {
                canvas.restore();
            }
        }
Пример #13
0
        void _drawValueIndicator(
            RenderBox parentBox,
            Canvas canvas,
            Offset center,
            Paint paint,
            float scale,
            TextPainter labelPainter
            )
        {
            canvas.save();
            canvas.translate(center.dx, center.dy);

            float textScaleFactor = labelPainter.height / _labelTextDesignSize;
            float overallScale    = scale * textScaleFactor;

            canvas.scale(overallScale, overallScale);
            float inverseTextScale = textScaleFactor != 0 ? 1.0f / textScaleFactor : 0.0f;
            float labelHalfWidth   = labelPainter.width / 2.0f;

            float halfWidthNeeded = Mathf.Max(
                0.0f,
                inverseTextScale * labelHalfWidth - (_topLobeRadius - _labelPadding)
                );

            float shift = this._getIdealOffset(parentBox, halfWidthNeeded, overallScale, center);
            float leftWidthNeeded;
            float rightWidthNeeded;

            if (shift < 0.0)
            {
                shift = Mathf.Max(shift, -halfWidthNeeded);
            }
            else
            {
                shift = Mathf.Min(shift, halfWidthNeeded);
            }

            rightWidthNeeded = halfWidthNeeded + shift;
            leftWidthNeeded  = halfWidthNeeded - shift;

            Path   path          = new Path();
            Offset bottomLobeEnd = this._addBottomLobe(path);

            float neckTriangleBase = _topNeckRadius - bottomLobeEnd.dx;

            float leftAmount  = Mathf.Max(0.0f, Mathf.Min(1.0f, leftWidthNeeded / neckTriangleBase));
            float rightAmount = Mathf.Max(0.0f, Mathf.Min(1.0f, rightWidthNeeded / neckTriangleBase));

            float  leftTheta      = (1.0f - leftAmount) * _thirtyDegrees;
            float  rightTheta     = (1.0f - rightAmount) * _thirtyDegrees;
            Offset neckLeftCenter = new Offset(
                -neckTriangleBase,
                _topLobeCenter.dy + Mathf.Cos(leftTheta) * _neckTriangleHypotenuse
                );
            Offset neckRightCenter = new Offset(
                neckTriangleBase,
                _topLobeCenter.dy + Mathf.Cos(rightTheta) * _neckTriangleHypotenuse
                );

            float leftNeckArcAngle  = _ninetyDegrees - leftTheta;
            float rightNeckArcAngle = Mathf.PI + _ninetyDegrees - rightTheta;

            float  neckStretchBaseline = bottomLobeEnd.dy - Mathf.Max(neckLeftCenter.dy, neckRightCenter.dy);
            float  t           = Mathf.Pow(inverseTextScale, 3.0f);
            float  stretch     = (neckStretchBaseline * t).clamp(0.0f, 10.0f * neckStretchBaseline);
            Offset neckStretch = new Offset(0.0f, neckStretchBaseline - stretch);

            D.assert(() => {
                if (!_debuggingLabelLocation)
                {
                    return(true);
                }

#pragma warning disable 0162
                Offset leftCenter  = _topLobeCenter - new Offset(leftWidthNeeded, 0.0f) + neckStretch;
                Offset rightCenter = _topLobeCenter + new Offset(rightWidthNeeded, 0.0f) + neckStretch;
                Rect valueRect     = Rect.fromLTRB(
                    leftCenter.dx - _topLobeRadius,
                    leftCenter.dy - _topLobeRadius,
                    rightCenter.dx + _topLobeRadius,
                    rightCenter.dy + _topLobeRadius
                    );
                Paint outlinePaint       = new Paint();
                outlinePaint.color       = new Color(0xffff0000);
                outlinePaint.style       = PaintingStyle.stroke;
                outlinePaint.strokeWidth = 1.0f;
                canvas.drawRect(valueRect, outlinePaint);
                return(true);

#pragma warning restore 0162
            });

            _addArc(
                path,
                neckLeftCenter + neckStretch,
                _topNeckRadius,
                0.0f,
                -leftNeckArcAngle
                );
            _addArc(
                path,
                _topLobeCenter - new Offset(leftWidthNeeded, 0.0f) + neckStretch,
                _topLobeRadius,
                _ninetyDegrees + leftTheta,
                _twoSeventyDegrees
                );
            _addArc(
                path,
                _topLobeCenter + new Offset(rightWidthNeeded, 0.0f) + neckStretch,
                _topLobeRadius,
                _twoSeventyDegrees,
                _twoSeventyDegrees + Mathf.PI - rightTheta
                );
            _addArc(
                path,
                neckRightCenter + neckStretch,
                _topNeckRadius,
                rightNeckArcAngle,
                Mathf.PI
                );
            canvas.drawPath(path, paint);

            canvas.save();
            canvas.translate(shift, -_distanceBetweenTopBottomCenters + neckStretch.dy);
            canvas.scale(inverseTextScale, inverseTextScale);
            labelPainter.paint(canvas, Offset.zero - new Offset(labelHalfWidth, labelPainter.height / 2.0f));
            canvas.restore();
            canvas.restore();
        }