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; } }
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(); }
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(); }
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(); }
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(); }
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(); }
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(); } }
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(); } }
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(); }