@@ -509,69 +509,47 @@ class _CanvasPool extends _SaveStackTracking {
509509 }
510510 }
511511
512+ // Float buffer used for path iteration.
513+ static Float32List _runBuffer = Float32List (PathRefIterator .kMaxBufferSize);
514+
512515 /// 'Runs' the given [path] by applying all of its commands to the canvas.
513516 void _runPath (html.CanvasRenderingContext2D ctx, SurfacePath path) {
514517 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 ' );
575553 }
576554 }
577555 }
0 commit comments