Skip to content

Commit

Permalink
[web] Update SurfacePath to use PathRef (#19557)
Browse files Browse the repository at this point in the history
* Update SurfacePath to use PathRef
* Fix test analysis errors
* Switch DDRect to use path to reduce paint time processing
* Implement toString() for debug mode
* Fix contains (bounds inclusive) edge case, add test
* Update recording canvas test for drawDRRect change
* Update diffrate for arc/conic render change
* Add test for winding for beveled border. Fix checkOnCurve
* Fix mono quad winding on curve check
* fix _chopCubicAtYExtrema and add test case
* Address reviewer comments / setAll API usage
  • Loading branch information
ferhatb authored Jul 9, 2020
1 parent 9b3e341 commit f10f172
Show file tree
Hide file tree
Showing 21 changed files with 5,322 additions and 1,657 deletions.
5 changes: 5 additions & 0 deletions ci/licenses_golden/licenses_flutter
Original file line number Diff line number Diff line change
Expand Up @@ -492,9 +492,14 @@ FILE: ../../../flutter/lib/web_ui/lib/src/engine/surface/offset.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/surface/opacity.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/surface/painting.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/surface/path/conic.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/surface/path/cubic.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/surface/path/path.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/surface/path/path_metrics.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/surface/path/path_ref.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/surface/path/path_to_svg.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/surface/path/path_utils.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/surface/path/path_windings.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/surface/path/tangent.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/surface/picture.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/surface/platform_view.dart
FILE: ../../../flutter/lib/web_ui/lib/src/engine/surface/recording_canvas.dart
Expand Down
5 changes: 5 additions & 0 deletions lib/web_ui/lib/src/engine.dart
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,14 @@ part 'engine/surface/offset.dart';
part 'engine/surface/opacity.dart';
part 'engine/surface/painting.dart';
part 'engine/surface/path/conic.dart';
part 'engine/surface/path/cubic.dart';
part 'engine/surface/path/path.dart';
part 'engine/surface/path/path_metrics.dart';
part 'engine/surface/path/path_ref.dart';
part 'engine/surface/path/path_to_svg.dart';
part 'engine/surface/path/path_utils.dart';
part 'engine/surface/path/path_windings.dart';
part 'engine/surface/path/tangent.dart';
part 'engine/surface/picture.dart';
part 'engine/surface/platform_view.dart';
part 'engine/surface/recording_canvas.dart';
Expand Down
98 changes: 38 additions & 60 deletions lib/web_ui/lib/src/engine/canvas_pool.dart
Original file line number Diff line number Diff line change
Expand Up @@ -509,69 +509,47 @@ class _CanvasPool extends _SaveStackTracking {
}
}

// Float buffer used for path iteration.
static Float32List _runBuffer = Float32List(PathRefIterator.kMaxBufferSize);

/// 'Runs' the given [path] by applying all of its commands to the canvas.
void _runPath(html.CanvasRenderingContext2D ctx, SurfacePath path) {
ctx.beginPath();
final List<Subpath> subpaths = path.subpaths;
final int subpathCount = subpaths.length;
for (int subPathIndex = 0; subPathIndex < subpathCount; subPathIndex++) {
final Subpath subpath = subpaths[subPathIndex];
final List<PathCommand> commands = subpath.commands;
final int commandCount = commands.length;
for (int c = 0; c < commandCount; c++) {
final PathCommand command = commands[c];
switch (command.type) {
case PathCommandTypes.bezierCurveTo:
final BezierCurveTo curve = command as BezierCurveTo;
ctx.bezierCurveTo(
curve.x1, curve.y1, curve.x2, curve.y2, curve.x3, curve.y3);
break;
case PathCommandTypes.close:
ctx.closePath();
break;
case PathCommandTypes.ellipse:
final Ellipse ellipse = command as Ellipse;
if (c == 0) {
// Ellipses that start a new path need to set start point,
// otherwise it incorrectly uses last point.
ctx.moveTo(subpath.startX, subpath.startY);
}
DomRenderer.ellipse(ctx,
ellipse.x,
ellipse.y,
ellipse.radiusX,
ellipse.radiusY,
ellipse.rotation,
ellipse.startAngle,
ellipse.endAngle,
ellipse.anticlockwise);
break;
case PathCommandTypes.lineTo:
final LineTo lineTo = command as LineTo;
ctx.lineTo(lineTo.x, lineTo.y);
break;
case PathCommandTypes.moveTo:
final MoveTo moveTo = command as MoveTo;
ctx.moveTo(moveTo.x, moveTo.y);
break;
case PathCommandTypes.rRect:
final RRectCommand rrectCommand = command as RRectCommand;
_RRectToCanvasRenderer(ctx)
.render(rrectCommand.rrect, startNewPath: false);
break;
case PathCommandTypes.rect:
final RectCommand rectCommand = command as RectCommand;
ctx.rect(rectCommand.x, rectCommand.y, rectCommand.width,
rectCommand.height);
break;
case PathCommandTypes.quadraticCurveTo:
final QuadraticCurveTo quadraticCurveTo = command as QuadraticCurveTo;
ctx.quadraticCurveTo(quadraticCurveTo.x1, quadraticCurveTo.y1,
quadraticCurveTo.x2, quadraticCurveTo.y2);
break;
default:
throw UnimplementedError('Unknown path command $command');
}
final Float32List p = _runBuffer;
final PathRefIterator iter = PathRefIterator(path.pathRef);
int verb = 0;
while ((verb = iter.next(p)) != SPath.kDoneVerb) {
switch (verb) {
case SPath.kMoveVerb:
ctx.moveTo(p[0], p[1]);
break;
case SPath.kLineVerb:
ctx.lineTo(p[2], p[3]);
break;
case SPath.kCubicVerb:
ctx.bezierCurveTo(p[2], p[3], p[4], p[5], p[6], p[7]);
break;
case SPath.kQuadVerb:
ctx.quadraticCurveTo(p[2], p[3], p[4], p[5]);
break;
case SPath.kConicVerb:
final double w = iter.conicWeight;
Conic conic = Conic(p[0], p[1], p[2], p[3], p[4], p[5], w);
List<ui.Offset> points = conic.toQuads();
final int len = points.length;
for (int i = 1; i < len; i += 2) {
final double p1x = points[i].dx;
final double p1y = points[i].dy;
final double p2x = points[i + 1].dx;
final double p2y = points[i + 1].dy;
ctx.quadraticCurveTo(p1x, p1y, p2x, p2y);
}
break;
case SPath.kCloseVerb:
ctx.closePath();
break;
default:
throw UnimplementedError('Unknown path verb $verb');
}
}
}
Expand Down
13 changes: 6 additions & 7 deletions lib/web_ui/lib/src/engine/surface/clip.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.


part of engine;

/// Mixin used by surfaces that clip their contents using an overflowing DOM
Expand Down Expand Up @@ -261,15 +260,15 @@ class PersistedPhysicalShape extends PersistedContainerSurface
}
return;
} else {
final Ellipse? ellipse = path.webOnlyPathAsCircle;
if (ellipse != null) {
final double rx = ellipse.radiusX;
final double ry = ellipse.radiusY;
final ui.Rect? ovalRect = path.webOnlyPathAsCircle;
if (ovalRect != null) {
final double rx = ovalRect.width / 2.0;
final double ry = ovalRect.height / 2.0;
final String borderRadius =
rx == ry ? '${rx}px ' : '${rx}px ${ry}px ';
final html.CssStyleDeclaration style = rootElement!.style;
final double left = ellipse.x - rx;
final double top = ellipse.y - ry;
final double left = ovalRect.left;
final double top = ovalRect.top;
style
..left = '${left}px'
..top = '${top}px'
Expand Down
Loading

0 comments on commit f10f172

Please sign in to comment.