@@ -509,69 +509,47 @@ class _CanvasPool extends _SaveStackTracking {
509
509
}
510
510
}
511
511
512
+ // Float buffer used for path iteration.
513
+ static Float32List _runBuffer = Float32List (PathRefIterator .kMaxBufferSize);
514
+
512
515
/// 'Runs' the given [path] by applying all of its commands to the canvas.
513
516
void _runPath (html.CanvasRenderingContext2D ctx, SurfacePath path) {
514
517
ctx.beginPath ();
515
- final List <Subpath > subpaths = path.subpaths;
516
- final int subpathCount = subpaths.length;
517
- for (int subPathIndex = 0 ; subPathIndex < subpathCount; subPathIndex++ ) {
518
- final Subpath subpath = subpaths[subPathIndex];
519
- final List <PathCommand > commands = subpath.commands;
520
- final int commandCount = commands.length;
521
- for (int c = 0 ; c < commandCount; c++ ) {
522
- final PathCommand command = commands[c];
523
- switch (command.type) {
524
- case PathCommandTypes .bezierCurveTo:
525
- final BezierCurveTo curve = command as BezierCurveTo ;
526
- ctx.bezierCurveTo (
527
- curve.x1, curve.y1, curve.x2, curve.y2, curve.x3, curve.y3);
528
- break ;
529
- case PathCommandTypes .close:
530
- ctx.closePath ();
531
- break ;
532
- case PathCommandTypes .ellipse:
533
- final Ellipse ellipse = command as Ellipse ;
534
- if (c == 0 ) {
535
- // Ellipses that start a new path need to set start point,
536
- // otherwise it incorrectly uses last point.
537
- ctx.moveTo (subpath.startX, subpath.startY);
538
- }
539
- DomRenderer .ellipse (ctx,
540
- ellipse.x,
541
- ellipse.y,
542
- ellipse.radiusX,
543
- ellipse.radiusY,
544
- ellipse.rotation,
545
- ellipse.startAngle,
546
- ellipse.endAngle,
547
- ellipse.anticlockwise);
548
- break ;
549
- case PathCommandTypes .lineTo:
550
- final LineTo lineTo = command as LineTo ;
551
- ctx.lineTo (lineTo.x, lineTo.y);
552
- break ;
553
- case PathCommandTypes .moveTo:
554
- final MoveTo moveTo = command as MoveTo ;
555
- ctx.moveTo (moveTo.x, moveTo.y);
556
- break ;
557
- case PathCommandTypes .rRect:
558
- final RRectCommand rrectCommand = command as RRectCommand ;
559
- _RRectToCanvasRenderer (ctx)
560
- .render (rrectCommand.rrect, startNewPath: false );
561
- break ;
562
- case PathCommandTypes .rect:
563
- final RectCommand rectCommand = command as RectCommand ;
564
- ctx.rect (rectCommand.x, rectCommand.y, rectCommand.width,
565
- rectCommand.height);
566
- break ;
567
- case PathCommandTypes .quadraticCurveTo:
568
- final QuadraticCurveTo quadraticCurveTo = command as QuadraticCurveTo ;
569
- ctx.quadraticCurveTo (quadraticCurveTo.x1, quadraticCurveTo.y1,
570
- quadraticCurveTo.x2, quadraticCurveTo.y2);
571
- break ;
572
- default :
573
- throw UnimplementedError ('Unknown path command $command ' );
574
- }
518
+ final Float32List p = _runBuffer;
519
+ final PathRefIterator iter = PathRefIterator (path.pathRef);
520
+ int verb = 0 ;
521
+ while ((verb = iter.next (p)) != SPath .kDoneVerb) {
522
+ switch (verb) {
523
+ case SPath .kMoveVerb:
524
+ ctx.moveTo (p[0 ], p[1 ]);
525
+ break ;
526
+ case SPath .kLineVerb:
527
+ ctx.lineTo (p[2 ], p[3 ]);
528
+ break ;
529
+ case SPath .kCubicVerb:
530
+ ctx.bezierCurveTo (p[2 ], p[3 ], p[4 ], p[5 ], p[6 ], p[7 ]);
531
+ break ;
532
+ case SPath .kQuadVerb:
533
+ ctx.quadraticCurveTo (p[2 ], p[3 ], p[4 ], p[5 ]);
534
+ break ;
535
+ case SPath .kConicVerb:
536
+ final double w = iter.conicWeight;
537
+ Conic conic = Conic (p[0 ], p[1 ], p[2 ], p[3 ], p[4 ], p[5 ], w);
538
+ List <ui.Offset > points = conic.toQuads ();
539
+ final int len = points.length;
540
+ for (int i = 1 ; i < len; i += 2 ) {
541
+ final double p1x = points[i].dx;
542
+ final double p1y = points[i].dy;
543
+ final double p2x = points[i + 1 ].dx;
544
+ final double p2y = points[i + 1 ].dy;
545
+ ctx.quadraticCurveTo (p1x, p1y, p2x, p2y);
546
+ }
547
+ break ;
548
+ case SPath .kCloseVerb:
549
+ ctx.closePath ();
550
+ break ;
551
+ default :
552
+ throw UnimplementedError ('Unknown path verb $verb ' );
575
553
}
576
554
}
577
555
}
0 commit comments