@@ -54,16 +54,37 @@ class CanvasPool extends _SaveStackTracking {
5454 // List of canvases available to reuse from prior paint cycle.
5555 List <html.CanvasElement >? _reusablePool;
5656 // Current canvas element or null if marked for lazy allocation.
57- html.CanvasElement ? get canvas => _canvas;
5857 html.CanvasElement ? _canvas;
5958
6059 html.HtmlElement ? _rootElement;
6160 int _saveContextCount = 0 ;
6261 final double _density;
6362
63+ /// Initializes canvas pool for target size and dpi.
6464 CanvasPool (this ._widthInBitmapPixels, this ._heightInBitmapPixels,
6565 this ._density);
6666
67+ /// Initializes canvas pool to be hosted on a surface.
68+ void mount (html.HtmlElement rootElement) {
69+ _rootElement = rootElement;
70+ }
71+
72+ /// Sets the translate transform to be applied to canvas to compensate for
73+ /// pixel padding applied to hosting [BitmapCanvas] .
74+ ///
75+ /// Should be called during initialization after [CanvasPool] is mounted.
76+ set initialTransform (ui.Offset transform) {
77+ translate (transform.dx, transform.dy);
78+ }
79+
80+ /// Returns true if no canvas has been allocated yet.
81+ bool get isEmpty => _canvas == null ;
82+
83+ /// Returns true if a canvas has been allocated for use.
84+ bool get isNotEmpty => _canvas != null ;
85+
86+
87+ /// Returns [CanvasRenderingContext2D] api to draw into this canvas.
6788 html.CanvasRenderingContext2D get context {
6889 html.CanvasRenderingContext2D ? ctx = _context;
6990 if (ctx == null ) {
@@ -75,6 +96,8 @@ class CanvasPool extends _SaveStackTracking {
7596 return ctx;
7697 }
7798
99+ /// Returns [ContextStateHandle] API to efficiently update state of
100+ /// drawing context.
78101 ContextStateHandle get contextHandle {
79102 if (_canvas == null ) {
80103 _createCanvas ();
@@ -84,11 +107,11 @@ class CanvasPool extends _SaveStackTracking {
84107 return _contextHandle! ;
85108 }
86109
87- // Prevents active canvas to be used for rendering and prepares a new
88- // canvas allocation on next drawing request that will require one.
89- //
90- // Saves current canvas so we can dispose
91- // and replay the clip/transform stack on top of new canvas.
110+ /// Prevents active canvas to be used for rendering and prepares a new
111+ /// canvas allocation on next drawing request that will require one.
112+ ///
113+ /// Saves current canvas so we can dispose
114+ /// and replay the clip/transform stack on top of new canvas.
92115 void closeCurrentCanvas () {
93116 assert (_rootElement != null );
94117 // Place clean copy of current canvas with context stack restored and paint
@@ -104,10 +127,6 @@ class CanvasPool extends _SaveStackTracking {
104127 }
105128 }
106129
107- void allocateCanvas (html.HtmlElement rootElement) {
108- _rootElement = rootElement;
109- }
110-
111130 void _createCanvas () {
112131 bool requiresClearRect = false ;
113132 bool reused = false ;
@@ -227,11 +246,6 @@ class CanvasPool extends _SaveStackTracking {
227246 }
228247 }
229248 reuse ();
230- resetTransform ();
231- }
232-
233- set initialTransform (ui.Offset transform) {
234- translate (transform.dx, transform.dy);
235249 }
236250
237251 int _replaySingleSaveEntry (int clipDepth, Matrix4 prevTransform,
@@ -311,7 +325,7 @@ class CanvasPool extends _SaveStackTracking {
311325 clipDepth, prevTransform, _currentTransform, clipStack);
312326 }
313327
314- // Marks this pool for reuse.
328+ /// Marks this pool for reuse.
315329 void reuse () {
316330 if (_canvas != null ) {
317331 _restoreContextSave ();
@@ -326,8 +340,11 @@ class CanvasPool extends _SaveStackTracking {
326340 _canvas = null ;
327341 _context = null ;
328342 _contextHandle = null ;
343+ _resetTransform ();
329344 }
330345
346+ /// Signals to canvas pool the end of drawing commands so cached resources
347+ /// that are reused from last instance can be cleanup.
331348 void endOfPaint () {
332349 if (_reusablePool != null ) {
333350 for (final html.CanvasElement e in _reusablePool! ) {
@@ -375,16 +392,16 @@ class CanvasPool extends _SaveStackTracking {
375392 double get dpi =>
376393 EnginePlatformDispatcher .browserDevicePixelRatio * _density;
377394
378- void resetTransform () {
395+ void _resetTransform () {
379396 final html.CanvasElement ? canvas = _canvas;
380397 if (canvas != null ) {
381398 canvas.style.transformOrigin = '' ;
382399 canvas.style.transform = '' ;
383400 }
384401 }
385402
386- // Returns a "data://" URI containing a representation of the image in this
387- // canvas in PNG format.
403+ /// Returns a "data://" URI containing a representation of the image in this
404+ /// canvas in PNG format.
388405 String toDataUrl () => _canvas? .toDataUrl () ?? '' ;
389406
390407 @override
@@ -518,6 +535,7 @@ class CanvasPool extends _SaveStackTracking {
518535 }
519536 }
520537
538+ /// Fill a virtually infinite rect with a color and optional blendMode.
521539 void drawColor (ui.Color color, ui.BlendMode blendMode) {
522540 final html.CanvasRenderingContext2D ctx = context;
523541 contextHandle.blendMode = blendMode;
@@ -531,7 +549,7 @@ class CanvasPool extends _SaveStackTracking {
531549 ctx.fillRect (- 10000 , - 10000 , 20000 , 20000 );
532550 }
533551
534- // Fill a virtually infinite rect with the color.
552+ /// Fill a virtually infinite rect with the color.
535553 void fill () {
536554 final html.CanvasRenderingContext2D ctx = context;
537555 ctx.beginPath ();
@@ -540,6 +558,7 @@ class CanvasPool extends _SaveStackTracking {
540558 ctx.fillRect (- 10000 , - 10000 , 20000 , 20000 );
541559 }
542560
561+ /// Draws a line from [p1] to [p2] .
543562 void strokeLine (ui.Offset p1, ui.Offset p2) {
544563 final html.CanvasRenderingContext2D ctx = context;
545564 ctx.beginPath ();
@@ -554,6 +573,8 @@ class CanvasPool extends _SaveStackTracking {
554573 ctx.stroke ();
555574 }
556575
576+ /// Draws a set of points with given radius, lines between points or
577+ /// a polygon.
557578 void drawPoints (ui.PointMode pointMode, Float32List points, double radius) {
558579 final html.CanvasRenderingContext2D ctx = context;
559580 final int len = points.length;
@@ -634,6 +655,19 @@ class CanvasPool extends _SaveStackTracking {
634655 }
635656 }
636657
658+ /// Draws a rectangle filled or stroked based on [style] .
659+ void drawRect (ui.Rect rect, ui.PaintingStyle ? style) {
660+ context.beginPath ();
661+ final ui.Rect ? shaderBounds = contextHandle._shaderBounds;
662+ if (shaderBounds == null ) {
663+ context.rect (rect.left, rect.top, rect.width, rect.height);
664+ } else {
665+ context.rect (rect.left - shaderBounds.left, rect.top - shaderBounds.top,
666+ rect.width, rect.height);
667+ }
668+ contextHandle.paint (style);
669+ }
670+
637671 /// Applies path to drawing context, preparing for fill and other operations.
638672 ///
639673 /// WARNING: Don't refactor _runPath/_runPathWithOffset. Latency sensitive
@@ -682,18 +716,7 @@ class CanvasPool extends _SaveStackTracking {
682716 }
683717 }
684718
685- void drawRect (ui.Rect rect, ui.PaintingStyle ? style) {
686- context.beginPath ();
687- final ui.Rect ? shaderBounds = contextHandle._shaderBounds;
688- if (shaderBounds == null ) {
689- context.rect (rect.left, rect.top, rect.width, rect.height);
690- } else {
691- context.rect (rect.left - shaderBounds.left, rect.top - shaderBounds.top,
692- rect.width, rect.height);
693- }
694- contextHandle.paint (style);
695- }
696-
719+ /// Draws a rounded rectangle filled or stroked based on [style] .
697720 void drawRRect (ui.RRect roundRect, ui.PaintingStyle ? style) {
698721 final ui.Rect ? shaderBounds = contextHandle._shaderBounds;
699722 RRectToCanvasRenderer (context).render (
@@ -702,6 +725,9 @@ class CanvasPool extends _SaveStackTracking {
702725 contextHandle.paint (style);
703726 }
704727
728+ /// Fills or strokes the area between [outer] and [inner] rounded rectangles.
729+ ///
730+ /// Typically used to draw a thick round border.
705731 void drawDRRect (ui.RRect outer, ui.RRect inner, ui.PaintingStyle ? style) {
706732 final RRectRenderer renderer = RRectToCanvasRenderer (context);
707733 final ui.Rect ? shaderBounds = contextHandle._shaderBounds;
@@ -716,6 +742,7 @@ class CanvasPool extends _SaveStackTracking {
716742 contextHandle.paint (style);
717743 }
718744
745+ /// Draws an axis-aligned oval that fills the given axis-aligned rectangle.
719746 void drawOval (ui.Rect rect, ui.PaintingStyle ? style) {
720747 context.beginPath ();
721748 final ui.Rect ? shaderBounds = contextHandle._shaderBounds;
@@ -728,6 +755,7 @@ class CanvasPool extends _SaveStackTracking {
728755 contextHandle.paint (style);
729756 }
730757
758+ /// Draws a circle centered at [c] with [radius] .
731759 void drawCircle (ui.Offset c, double radius, ui.PaintingStyle ? style) {
732760 context.beginPath ();
733761 final ui.Rect ? shaderBounds = contextHandle._shaderBounds;
@@ -737,6 +765,7 @@ class CanvasPool extends _SaveStackTracking {
737765 contextHandle.paint (style);
738766 }
739767
768+ /// Draws or strokes a path based on [style] and current context state.
740769 void drawPath (ui.Path path, ui.PaintingStyle ? style) {
741770 final ui.Rect ? shaderBounds = contextHandle._shaderBounds;
742771 if (shaderBounds == null ) {
@@ -748,6 +777,7 @@ class CanvasPool extends _SaveStackTracking {
748777 contextHandle.paintPath (style, path.fillType);
749778 }
750779
780+ /// Draws a shadow for a Path representing the given material elevation.
751781 void drawShadow (ui.Path path, ui.Color color, double elevation,
752782 bool transparentOccluder) {
753783 final SurfaceShadowData ? shadow = computeShadow (path.getBounds (), elevation);
@@ -810,6 +840,11 @@ class CanvasPool extends _SaveStackTracking {
810840 }
811841 }
812842
843+ /// Disposes html canvas element(s) used by this pool when persistent surface
844+ /// is disposed.
845+ ///
846+ /// When this pool is reused, [clear] is called instead to be able to
847+ /// draw using existing canvas elements.
813848 void dispose () {
814849 // Webkit has a threshold for the amount of canvas pixels an app can
815850 // allocate. Even though our canvases are being garbage-collected as
@@ -836,16 +871,18 @@ class CanvasPool extends _SaveStackTracking {
836871 }
837872}
838873
839- // Optimizes applying paint parameters to html canvas.
840- //
841- // See https://www.w3.org/TR/2dcontext/ for defaults used in this class
842- // to initialize current values.
843- //
874+ /// Optimizes applying paint parameters to html canvas.
875+ ///
876+ /// See https://www.w3.org/TR/2dcontext/ for defaults used in this class
877+ /// to initialize current values.
844878class ContextStateHandle {
879+ /// Associated canvas element context tracked by this context state.
845880 final html.CanvasRenderingContext2D context;
846881 final CanvasPool _canvasPool;
882+ /// Dpi of context.
847883 final double density;
848884
885+ /// Initializes context state for a [CanvasPool] .
849886 ContextStateHandle (this ._canvasPool, this .context, this .density);
850887 ui.BlendMode ? _currentBlendMode = ui.BlendMode .srcOver;
851888 ui.StrokeCap ? _currentStrokeCap = ui.StrokeCap .butt;
@@ -856,6 +893,7 @@ class ContextStateHandle {
856893 Object ? _currentStrokeStyle;
857894 double _currentLineWidth = 1.0 ;
858895
896+ /// See [html.CanvasRenderingContext2D] .
859897 set blendMode (ui.BlendMode ? blendMode) {
860898 if (blendMode != _currentBlendMode) {
861899 _currentBlendMode = blendMode;
@@ -864,6 +902,7 @@ class ContextStateHandle {
864902 }
865903 }
866904
905+ /// See [html.CanvasRenderingContext2D] .
867906 set strokeCap (ui.StrokeCap ? strokeCap) {
868907 strokeCap ?? = ui.StrokeCap .butt;
869908 if (strokeCap != _currentStrokeCap) {
@@ -872,13 +911,15 @@ class ContextStateHandle {
872911 }
873912 }
874913
914+ /// See [html.CanvasRenderingContext2D] .
875915 set lineWidth (double lineWidth) {
876916 if (lineWidth != _currentLineWidth) {
877917 _currentLineWidth = lineWidth;
878918 context.lineWidth = lineWidth;
879919 }
880920 }
881921
922+ /// See [html.CanvasRenderingContext2D] .
882923 set strokeJoin (ui.StrokeJoin ? strokeJoin) {
883924 strokeJoin ?? = ui.StrokeJoin .miter;
884925 if (strokeJoin != _currentStrokeJoin) {
@@ -887,13 +928,15 @@ class ContextStateHandle {
887928 }
888929 }
889930
931+ /// See [html.CanvasRenderingContext2D] .
890932 set fillStyle (Object ? colorOrGradient) {
891933 if (! identical (colorOrGradient, _currentFillStyle)) {
892934 _currentFillStyle = colorOrGradient;
893935 context.fillStyle = colorOrGradient;
894936 }
895937 }
896938
939+ /// See [html.CanvasRenderingContext2D] .
897940 set strokeStyle (Object ? colorOrGradient) {
898941 if (! identical (colorOrGradient, _currentStrokeStyle)) {
899942 _currentStrokeStyle = colorOrGradient;
@@ -1052,6 +1095,7 @@ class ContextStateHandle {
10521095 }
10531096 }
10541097
1098+ /// Fills or strokes the currently active path.
10551099 void paint (ui.PaintingStyle ? style) {
10561100 if (style == ui.PaintingStyle .stroke) {
10571101 context.stroke ();
@@ -1060,6 +1104,7 @@ class ContextStateHandle {
10601104 }
10611105 }
10621106
1107+ /// Fills or strokes the currently active path based on fill type.
10631108 void paintPath (ui.PaintingStyle ? style, ui.PathFillType pathFillType) {
10641109 if (style == ui.PaintingStyle .stroke) {
10651110 context.stroke ();
@@ -1072,6 +1117,8 @@ class ContextStateHandle {
10721117 }
10731118 }
10741119
1120+ /// Resets drawing context state to defaults for
1121+ /// [html.CanvasRenderingContext2D] .
10751122 void reset () {
10761123 context.fillStyle = '' ;
10771124 // Read back fillStyle/strokeStyle values from context so that input such
0 commit comments