mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Implement Canvas drawPoints API for Html backend (#15870)
This commit is contained in:
parent
cb5e7fe12c
commit
3d5bbb4371
@ -1,2 +1,2 @@
|
||||
repository: https://github.com/flutter/goldens.git
|
||||
revision: 30ef2668489dab3191a5df251330aedb9b0c239a
|
||||
revision: 3db2bb2329e7277c34389a92507eacaab774c8e8
|
||||
|
||||
@ -570,6 +570,25 @@ class BitmapCanvas extends EngineCanvas {
|
||||
_canvasPool.currentTransform, vertices, blendMode, paint);
|
||||
}
|
||||
|
||||
@override
|
||||
void drawPoints(ui.PointMode pointMode, Float32List points,
|
||||
double strokeWidth, ui.Color color) {
|
||||
ContextStateHandle contextHandle = _canvasPool.contextHandle;
|
||||
contextHandle
|
||||
..lineWidth = strokeWidth
|
||||
..blendMode = ui.BlendMode.srcOver
|
||||
..strokeCap = ui.StrokeCap.round
|
||||
..strokeJoin = ui.StrokeJoin.round
|
||||
..filter = '';
|
||||
final String cssColor = colorToCssString(color);
|
||||
if (pointMode == ui.PointMode.points) {
|
||||
contextHandle.fillStyle = cssColor;
|
||||
} else {
|
||||
contextHandle.strokeStyle = cssColor;
|
||||
}
|
||||
_canvasPool.drawPoints(pointMode, points, strokeWidth / 2.0);
|
||||
}
|
||||
|
||||
@override
|
||||
void endOfPaint() {
|
||||
assert(_saveCount == 0);
|
||||
|
||||
@ -229,7 +229,8 @@ class _CanvasPool extends _SaveStackTracking {
|
||||
|
||||
// This scale makes sure that 1 CSS pixel is translated to the correct
|
||||
// number of bitmap pixels.
|
||||
ctx.scale(EngineWindow.browserDevicePixelRatio, EngineWindow.browserDevicePixelRatio);
|
||||
ctx.scale(EngineWindow.browserDevicePixelRatio,
|
||||
EngineWindow.browserDevicePixelRatio);
|
||||
}
|
||||
|
||||
void resetTransform() {
|
||||
@ -397,6 +398,38 @@ class _CanvasPool extends _SaveStackTracking {
|
||||
ctx.stroke();
|
||||
}
|
||||
|
||||
void drawPoints(ui.PointMode pointMode, Float32List points, double radius) {
|
||||
html.CanvasRenderingContext2D ctx = context;
|
||||
final int len = points.length;
|
||||
switch (pointMode) {
|
||||
case ui.PointMode.points:
|
||||
for (int i = 0; i < len; i += 2) {
|
||||
final double x = points[i];
|
||||
final double y = points[i + 1];
|
||||
ctx.beginPath();
|
||||
ctx.arc(x, y, radius, 0, 2.0 * math.pi);
|
||||
ctx.fill();
|
||||
}
|
||||
break;
|
||||
case ui.PointMode.lines:
|
||||
ctx.beginPath();
|
||||
for (int i = 0; i < (len - 2); i += 4) {
|
||||
ctx.moveTo(points[i], points[i + 1]);
|
||||
ctx.lineTo(points[i + 2], points[i + 3]);
|
||||
ctx.stroke();
|
||||
}
|
||||
break;
|
||||
case ui.PointMode.polygon:
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(points[0], points[1]);
|
||||
for (int i = 2; i < len; i += 2) {
|
||||
ctx.lineTo(points[i], points[i + 1]);
|
||||
}
|
||||
ctx.stroke();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/// 'Runs' the given [path] by applying all of its commands to the canvas.
|
||||
void _runPath(html.CanvasRenderingContext2D ctx, SurfacePath path) {
|
||||
ctx.beginPath();
|
||||
|
||||
@ -104,8 +104,8 @@ class DomCanvas extends EngineCanvas with SaveElementStackTracking {
|
||||
..transformOrigin = '0 0 0'
|
||||
..transform = effectiveTransform;
|
||||
|
||||
final String cssColor = paint.color == null ? '#000000'
|
||||
: colorToCssString(paint.color);
|
||||
final String cssColor =
|
||||
paint.color == null ? '#000000' : colorToCssString(paint.color);
|
||||
|
||||
if (paint.maskFilter != null) {
|
||||
style.filter = 'blur(${paint.maskFilter.webOnlySigma}px)';
|
||||
@ -181,6 +181,12 @@ class DomCanvas extends EngineCanvas with SaveElementStackTracking {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
void drawPoints(ui.PointMode pointMode, Float32List points,
|
||||
double strokeWidth, ui.Color color) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
void endOfPaint() {
|
||||
// No reuse of elements yet to handle here. Noop.
|
||||
|
||||
@ -69,6 +69,9 @@ abstract class EngineCanvas {
|
||||
void drawVertices(
|
||||
ui.Vertices vertices, ui.BlendMode blendMode, SurfacePaintData paint);
|
||||
|
||||
void drawPoints(ui.PointMode pointMode, Float32List points,
|
||||
double strokeWidth, ui.Color color);
|
||||
|
||||
/// Extension of Canvas API to mark the end of a stream of painting commands
|
||||
/// to enable re-use/dispose optimizations.
|
||||
void endOfPaint();
|
||||
|
||||
@ -234,6 +234,12 @@ class HoudiniCanvas extends EngineCanvas with SaveElementStackTracking {
|
||||
// TODO(flutter_web): implement.
|
||||
}
|
||||
|
||||
@override
|
||||
void drawPoints(ui.PointMode pointMode, Float32List points,
|
||||
double strokeWidth, ui.Color color) {
|
||||
// TODO(flutter_web): implement.
|
||||
}
|
||||
|
||||
@override
|
||||
void endOfPaint() {}
|
||||
}
|
||||
|
||||
@ -253,17 +253,28 @@ class RecordingCanvas {
|
||||
final ui.RRect scaledOuter = outer.scaleRadii();
|
||||
final ui.RRect scaledInner = inner.scaleRadii();
|
||||
|
||||
final double outerTl = _measureBorderRadius(scaledOuter.tlRadiusX, scaledOuter.tlRadiusY);
|
||||
final double outerTr = _measureBorderRadius(scaledOuter.trRadiusX, scaledOuter.trRadiusY);
|
||||
final double outerBl = _measureBorderRadius(scaledOuter.blRadiusX, scaledOuter.blRadiusY);
|
||||
final double outerBr = _measureBorderRadius(scaledOuter.brRadiusX, scaledOuter.brRadiusY);
|
||||
final double outerTl =
|
||||
_measureBorderRadius(scaledOuter.tlRadiusX, scaledOuter.tlRadiusY);
|
||||
final double outerTr =
|
||||
_measureBorderRadius(scaledOuter.trRadiusX, scaledOuter.trRadiusY);
|
||||
final double outerBl =
|
||||
_measureBorderRadius(scaledOuter.blRadiusX, scaledOuter.blRadiusY);
|
||||
final double outerBr =
|
||||
_measureBorderRadius(scaledOuter.brRadiusX, scaledOuter.brRadiusY);
|
||||
|
||||
final double innerTl = _measureBorderRadius(scaledInner.tlRadiusX, scaledInner.tlRadiusY);
|
||||
final double innerTr = _measureBorderRadius(scaledInner.trRadiusX, scaledInner.trRadiusY);
|
||||
final double innerBl = _measureBorderRadius(scaledInner.blRadiusX, scaledInner.blRadiusY);
|
||||
final double innerBr = _measureBorderRadius(scaledInner.brRadiusX, scaledInner.brRadiusY);
|
||||
final double innerTl =
|
||||
_measureBorderRadius(scaledInner.tlRadiusX, scaledInner.tlRadiusY);
|
||||
final double innerTr =
|
||||
_measureBorderRadius(scaledInner.trRadiusX, scaledInner.trRadiusY);
|
||||
final double innerBl =
|
||||
_measureBorderRadius(scaledInner.blRadiusX, scaledInner.blRadiusY);
|
||||
final double innerBr =
|
||||
_measureBorderRadius(scaledInner.brRadiusX, scaledInner.brRadiusY);
|
||||
|
||||
if (innerTl > outerTl || innerTr > outerTr || innerBl > outerBl || innerBr > outerBr) {
|
||||
if (innerTl > outerTl ||
|
||||
innerTr > outerTr ||
|
||||
innerBl > outerBl ||
|
||||
innerBr > outerBr) {
|
||||
return; // Some inner radius is overlapping some outer radius
|
||||
}
|
||||
|
||||
@ -323,7 +334,8 @@ class RecordingCanvas {
|
||||
_commands.add(PaintDrawImage(image, offset, paint.paintData));
|
||||
}
|
||||
|
||||
void drawImageRect(ui.Image image, ui.Rect src, ui.Rect dst, SurfacePaint paint) {
|
||||
void drawImageRect(
|
||||
ui.Image image, ui.Rect src, ui.Rect dst, SurfacePaint paint) {
|
||||
_hasArbitraryPaint = true;
|
||||
_didDraw = true;
|
||||
_paintBounds.grow(dst);
|
||||
@ -358,18 +370,33 @@ class RecordingCanvas {
|
||||
_commands.add(PaintDrawShadow(path, color, elevation, transparentOccluder));
|
||||
}
|
||||
|
||||
void drawVertices(ui.Vertices vertices, ui.BlendMode blendMode,
|
||||
SurfacePaint paint) {
|
||||
void drawVertices(
|
||||
ui.Vertices vertices, ui.BlendMode blendMode, SurfacePaint paint) {
|
||||
_hasArbitraryPaint = true;
|
||||
_didDraw = true;
|
||||
final Float32List positions = vertices.positions;
|
||||
assert(positions.length >= 2);
|
||||
_growPaintBoundsByPoints(vertices.positions, 0);
|
||||
_commands.add(PaintVertices(vertices, blendMode, paint.paintData));
|
||||
}
|
||||
|
||||
void drawRawPoints(
|
||||
ui.PointMode pointMode, Float32List points, ui.Paint paint) {
|
||||
if (paint.strokeWidth == null) {
|
||||
return;
|
||||
}
|
||||
_hasArbitraryPaint = true;
|
||||
_didDraw = true;
|
||||
_growPaintBoundsByPoints(points, paint.strokeWidth);
|
||||
_commands
|
||||
.add(PaintPoints(pointMode, points, paint.strokeWidth, paint.color));
|
||||
}
|
||||
|
||||
void _growPaintBoundsByPoints(Float32List points, double thickness) {
|
||||
double minValueX, maxValueX, minValueY, maxValueY;
|
||||
minValueX = maxValueX = positions[0];
|
||||
minValueY = maxValueY = positions[1];
|
||||
for (int i = 2, len = positions.length; i < len; i += 2) {
|
||||
final double x = positions[i];
|
||||
final double y = positions[i + 1];
|
||||
minValueX = maxValueX = points[0];
|
||||
minValueY = maxValueY = points[1];
|
||||
for (int i = 2, len = points.length; i < len; i += 2) {
|
||||
final double x = points[i];
|
||||
final double y = points[i + 1];
|
||||
if (x.isNaN || y.isNaN) {
|
||||
// Follows skia implementation that sets bounds to empty
|
||||
// and aborts.
|
||||
@ -380,8 +407,9 @@ class RecordingCanvas {
|
||||
minValueY = math.min(minValueY, y);
|
||||
maxValueY = math.max(maxValueY, y);
|
||||
}
|
||||
_paintBounds.growLTRB(minValueX, minValueY, maxValueX, maxValueY);
|
||||
_commands.add(PaintVertices(vertices, blendMode, paint.paintData));
|
||||
final double distance = thickness / 2.0;
|
||||
_paintBounds.growLTRB(minValueX - distance, minValueY - distance,
|
||||
maxValueX + distance, maxValueY + distance);
|
||||
}
|
||||
|
||||
int _saveCount = 1;
|
||||
@ -677,7 +705,8 @@ class PaintDrawColor extends PaintCommand {
|
||||
|
||||
@override
|
||||
void serializeToCssPaint(List<List<dynamic>> serializedCommands) {
|
||||
serializedCommands.add(<dynamic>[11, colorToCssString(color), blendMode.index]);
|
||||
serializedCommands
|
||||
.add(<dynamic>[11, colorToCssString(color), blendMode.index]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -766,6 +795,33 @@ class PaintVertices extends PaintCommand {
|
||||
}
|
||||
}
|
||||
|
||||
class PaintPoints extends PaintCommand {
|
||||
final Float32List points;
|
||||
final ui.PointMode pointMode;
|
||||
final double strokeWidth;
|
||||
final ui.Color color;
|
||||
PaintPoints(this.pointMode, this.points, this.strokeWidth, this.color);
|
||||
|
||||
@override
|
||||
void apply(EngineCanvas canvas) {
|
||||
canvas.drawPoints(pointMode, points, strokeWidth, color);
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
if (assertionsEnabled) {
|
||||
return 'drawPoints($pointMode, $points, $strokeWidth, $color)';
|
||||
} else {
|
||||
return super.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
void serializeToCssPaint(List<List<dynamic>> serializedCommands) {
|
||||
throw UnimplementedError();
|
||||
}
|
||||
}
|
||||
|
||||
class PaintDrawRect extends PaintCommand {
|
||||
final ui.Rect rect;
|
||||
final SurfacePaintData paint;
|
||||
@ -1185,8 +1241,8 @@ abstract class PathCommand {
|
||||
|
||||
/// Helper method for implementing transforms.
|
||||
static ui.Offset _transformOffset(double x, double y, Float64List matrix4) =>
|
||||
ui.Offset((matrix4[0] * x) + (matrix4[4] * y) + matrix4[12],
|
||||
(matrix4[1] * x) + (matrix4[5] * y) + matrix4[13]);
|
||||
ui.Offset((matrix4[0] * x) + (matrix4[4] * y) + matrix4[12],
|
||||
(matrix4[1] * x) + (matrix4[5] * y) + matrix4[13]);
|
||||
}
|
||||
|
||||
class MoveTo extends PathCommand {
|
||||
@ -1291,16 +1347,29 @@ class Ellipse extends PathCommand {
|
||||
@override
|
||||
void transform(Float64List matrix4, ui.Path targetPath) {
|
||||
final ui.Path bezierPath = ui.Path();
|
||||
_drawArcWithBezier(x, y, radiusX, radiusY, rotation,
|
||||
startAngle,
|
||||
_drawArcWithBezier(
|
||||
x,
|
||||
y,
|
||||
radiusX,
|
||||
radiusY,
|
||||
rotation,
|
||||
startAngle,
|
||||
anticlockwise ? startAngle - endAngle : endAngle - startAngle,
|
||||
matrix4, bezierPath);
|
||||
matrix4,
|
||||
bezierPath);
|
||||
targetPath.addPath(bezierPath, ui.Offset.zero, matrix4: matrix4);
|
||||
}
|
||||
|
||||
void _drawArcWithBezier(double centerX, double centerY,
|
||||
double radiusX, double radiusY, double rotation, double startAngle,
|
||||
double sweep, Float64List matrix4, ui.Path targetPath) {
|
||||
void _drawArcWithBezier(
|
||||
double centerX,
|
||||
double centerY,
|
||||
double radiusX,
|
||||
double radiusY,
|
||||
double rotation,
|
||||
double startAngle,
|
||||
double sweep,
|
||||
Float64List matrix4,
|
||||
ui.Path targetPath) {
|
||||
double ratio = sweep.abs() / (math.pi / 2.0);
|
||||
if ((1.0 - ratio).abs() < 0.0000001) {
|
||||
ratio = 1.0;
|
||||
@ -1315,9 +1384,17 @@ class Ellipse extends PathCommand {
|
||||
}
|
||||
}
|
||||
|
||||
void _drawArcSegment(ui.Path path, double centerX, double centerY,
|
||||
double radiusX, double radiusY, double rotation, double startAngle,
|
||||
double sweep, bool startPath, Float64List matrix4) {
|
||||
void _drawArcSegment(
|
||||
ui.Path path,
|
||||
double centerX,
|
||||
double centerY,
|
||||
double radiusX,
|
||||
double radiusY,
|
||||
double rotation,
|
||||
double startAngle,
|
||||
double sweep,
|
||||
bool startPath,
|
||||
Float64List matrix4) {
|
||||
final double s = 4 / 3 * math.tan(sweep / 4);
|
||||
|
||||
// Rotate unit vector to startAngle and endAngle to use for computing start
|
||||
@ -1352,18 +1429,19 @@ class Ellipse extends PathCommand {
|
||||
}
|
||||
}
|
||||
if (rotation == 0.0) {
|
||||
path.cubicTo(centerX + cpx1, centerY + cpy1,
|
||||
centerX + cpx2, centerY + cpy2,
|
||||
endPointX, endPointY);
|
||||
path.cubicTo(centerX + cpx1, centerY + cpy1, centerX + cpx2,
|
||||
centerY + cpy2, endPointX, endPointY);
|
||||
} else {
|
||||
final double rotatedCpx1 = centerX + (cpx1 * cosR) + (cpy1 * sinR);
|
||||
final double rotatedCpy1 = centerY + (cpy1 * cosR) - (cpx1 * sinR);
|
||||
final double rotatedCpx2 = centerX + (cpx2 * cosR) + (cpy2 * sinR);
|
||||
final double rotatedCpy2 = centerY + (cpy2 * cosR) - (cpx2 * sinR);
|
||||
final double rotatedEndX = centerX + ((endPointX - centerX) * cosR)
|
||||
+ ((endPointY - centerY) * sinR);
|
||||
final double rotatedEndY = centerY + ((endPointY - centerY) * cosR)
|
||||
- ((endPointX - centerX) * sinR);
|
||||
final double rotatedEndX = centerX +
|
||||
((endPointX - centerX) * cosR) +
|
||||
((endPointY - centerY) * sinR);
|
||||
final double rotatedEndY = centerY +
|
||||
((endPointY - centerY) * cosR) -
|
||||
((endPointX - centerX) * sinR);
|
||||
path.cubicTo(rotatedCpx1, rotatedCpy1, rotatedCpx2, rotatedCpy2,
|
||||
rotatedEndX, rotatedEndY);
|
||||
}
|
||||
@ -1411,8 +1489,8 @@ class QuadraticCurveTo extends PathCommand {
|
||||
final double transformedY1 = (m1 * x1) + (m5 * y1) + m13;
|
||||
final double transformedX2 = (m0 * x2) + (m4 * y2) + m12;
|
||||
final double transformedY2 = (m1 * x2) + (m5 * y2) + m13;
|
||||
targetPath.quadraticBezierTo(transformedX1, transformedY1,
|
||||
transformedX2, transformedY2);
|
||||
targetPath.quadraticBezierTo(
|
||||
transformedX1, transformedY1, transformedX2, transformedY2);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -1461,8 +1539,8 @@ class BezierCurveTo extends PathCommand {
|
||||
final double transformedY2 = (s1 * x2) + (s5 * y2) + s13;
|
||||
final double transformedX3 = (s0 * x3) + (s4 * y3) + s12;
|
||||
final double transformedY3 = (s1 * x3) + (s5 * y3) + s13;
|
||||
targetPath.cubicTo(transformedX1, transformedY1,
|
||||
transformedX2, transformedY2, transformedX3, transformedY3);
|
||||
targetPath.cubicTo(transformedX1, transformedY1, transformedX2,
|
||||
transformedY2, transformedX3, transformedY3);
|
||||
}
|
||||
|
||||
@override
|
||||
@ -1507,11 +1585,13 @@ class RectCommand extends PathCommand {
|
||||
final double transformedY3 = (s1 * x2) + (s5 * y2) + s13;
|
||||
final double transformedX4 = (s0 * x) + (s4 * y2) + s12;
|
||||
final double transformedY4 = (s1 * x) + (s5 * y2) + s13;
|
||||
if (transformedY1 == transformedY2 && transformedY3 == transformedY4 &&
|
||||
transformedX1 == transformedX4 && transformedX2 == transformedX3) {
|
||||
if (transformedY1 == transformedY2 &&
|
||||
transformedY3 == transformedY4 &&
|
||||
transformedX1 == transformedX4 &&
|
||||
transformedX2 == transformedX3) {
|
||||
// It is still a rectangle.
|
||||
targetPath.addRect(ui.Rect.fromLTRB(transformedX1, transformedY1,
|
||||
transformedX3, transformedY3));
|
||||
targetPath.addRect(ui.Rect.fromLTRB(
|
||||
transformedX1, transformedY1, transformedX3, transformedY3));
|
||||
} else {
|
||||
targetPath.moveTo(transformedX1, transformedY1);
|
||||
targetPath.lineTo(transformedX2, transformedY2);
|
||||
@ -1558,7 +1638,7 @@ class RRectCommand extends PathCommand {
|
||||
targetPath.addPath(roundRectPath, ui.Offset.zero, matrix4: matrix4);
|
||||
}
|
||||
|
||||
@override
|
||||
@override
|
||||
String toString() {
|
||||
if (assertionsEnabled) {
|
||||
return '$rrect';
|
||||
|
||||
@ -420,3 +420,17 @@ String canonicalizeFontFamily(String fontFamily) {
|
||||
}
|
||||
return '"$fontFamily", $_fallbackFontFamily, sans-serif';
|
||||
}
|
||||
|
||||
/// Converts a list of [Offset] to a typed array of floats.
|
||||
Float32List offsetListToFloat32List(List<ui.Offset> offsetList) {
|
||||
if (offsetList == null) {
|
||||
return null;
|
||||
}
|
||||
final int length = offsetList.length;
|
||||
final floatList = Float32List(length * 2);
|
||||
for (int i = 0, destIndex = 0; i < length; i++, destIndex += 2) {
|
||||
floatList[destIndex] = offsetList[i].dx;
|
||||
floatList[destIndex + 1] = offsetList[i].dy;
|
||||
}
|
||||
return floatList;
|
||||
}
|
||||
|
||||
@ -76,8 +76,9 @@ class Vertices {
|
||||
_mode = mode,
|
||||
_colors = _int32ListFromColors(colors),
|
||||
_indices = indices != null ? Uint16List.fromList(indices) : null,
|
||||
_positions = _offsetListToInt32List(positions),
|
||||
_textureCoordinates = _offsetListToInt32List(textureCoordinates) {
|
||||
_positions = engine.offsetListToFloat32List(positions),
|
||||
_textureCoordinates =
|
||||
engine.offsetListToFloat32List(textureCoordinates) {
|
||||
engine.initWebGl();
|
||||
}
|
||||
|
||||
@ -125,19 +126,6 @@ class Vertices {
|
||||
engine.initWebGl();
|
||||
}
|
||||
|
||||
static Float32List _offsetListToInt32List(List<Offset> offsetList) {
|
||||
if (offsetList == null) {
|
||||
return null;
|
||||
}
|
||||
final int length = offsetList.length;
|
||||
final floatList = Float32List(length * 2);
|
||||
for (int i = 0, destIndex = 0; i < length; i++, destIndex += 2) {
|
||||
floatList[destIndex] = offsetList[i].dx;
|
||||
floatList[destIndex + 1] = offsetList[i].dy;
|
||||
}
|
||||
return floatList;
|
||||
}
|
||||
|
||||
static Int32List _int32ListFromColors(List<Color> colors) {
|
||||
Int32List list = Int32List(colors.length);
|
||||
for (int i = 0, len = colors.length; i < len; i++) {
|
||||
@ -950,7 +938,8 @@ class Canvas {
|
||||
assert(pointMode != null);
|
||||
assert(points != null);
|
||||
assert(paint != null);
|
||||
throw UnimplementedError();
|
||||
final Float32List pointList = engine.offsetListToFloat32List(points);
|
||||
drawRawPoints(pointMode, pointList, paint);
|
||||
}
|
||||
|
||||
/// Draws a sequence of points according to the given [PointMode].
|
||||
@ -969,7 +958,7 @@ class Canvas {
|
||||
if (points.length % 2 != 0) {
|
||||
throw ArgumentError('"points" must have an even number of values.');
|
||||
}
|
||||
throw UnimplementedError();
|
||||
_canvas.drawRawPoints(pointMode, points, paint);
|
||||
}
|
||||
|
||||
void drawVertices(Vertices vertices, BlendMode blendMode, Paint paint) {
|
||||
|
||||
@ -0,0 +1,56 @@
|
||||
// Copyright 2013 The Flutter Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'dart:html' as html;
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:ui/src/engine.dart';
|
||||
import 'package:ui/ui.dart';
|
||||
|
||||
import 'package:test/test.dart';
|
||||
|
||||
import 'package:web_engine_tester/golden_tester.dart';
|
||||
|
||||
void main() async {
|
||||
final Rect region = Rect.fromLTWH(0, 0, 400, 600);
|
||||
|
||||
BitmapCanvas canvas;
|
||||
|
||||
setUp(() {
|
||||
canvas = BitmapCanvas(region);
|
||||
});
|
||||
|
||||
tearDown(() {
|
||||
canvas.rootElement.remove();
|
||||
});
|
||||
|
||||
test('draws points in all 3 modes', () async {
|
||||
final double strokeWidth = 2.0;
|
||||
final Color color = Color(0xFF0000FF);
|
||||
final Float32List points = offsetListToFloat32List(<Offset>[
|
||||
Offset(10, 10),
|
||||
Offset(50, 10),
|
||||
Offset(70, 70),
|
||||
Offset(170, 70)
|
||||
]);
|
||||
canvas.drawPoints(PointMode.points, points, strokeWidth, color);
|
||||
final Float32List points2 = offsetListToFloat32List(<Offset>[
|
||||
Offset(10, 110),
|
||||
Offset(50, 110),
|
||||
Offset(70, 170),
|
||||
Offset(170, 170)
|
||||
]);
|
||||
canvas.drawPoints(PointMode.lines, points2, strokeWidth, color);
|
||||
final Float32List points3 = offsetListToFloat32List(<Offset>[
|
||||
Offset(10, 210),
|
||||
Offset(50, 210),
|
||||
Offset(70, 270),
|
||||
Offset(170, 270)
|
||||
]);
|
||||
canvas.drawPoints(PointMode.polygon, points3, strokeWidth, color);
|
||||
|
||||
html.document.body.append(canvas.rootElement);
|
||||
await matchGoldenFile('canvas_draw_points.png', region: region);
|
||||
}, timeout: const Timeout(Duration(seconds: 10)));
|
||||
}
|
||||
@ -229,6 +229,17 @@ class MockEngineCanvas implements EngineCanvas {
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void drawPoints(PointMode pointMode, Float32List points, double strokeWidth,
|
||||
Color color) {
|
||||
_called('drawPoints', arguments: <String, dynamic>{
|
||||
'pointMode': pointMode,
|
||||
'points': points,
|
||||
'strokeWidth': strokeWidth,
|
||||
'color': color,
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void endOfPaint() {
|
||||
_called('endOfPaint', arguments: <String, dynamic>{});
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user