@@ -89,22 +89,20 @@ class Surface {
8989 _addedToScene = true ;
9090 }
9191
92+ ui.Size ? _currentSize;
93+
9294 void _createOrUpdateSurfaces (ui.Size size) {
9395 if (size.isEmpty) {
9496 throw CanvasKitError ('Cannot create surfaces of empty size.' );
9597 }
9698
97- final CkSurface ? currentSurface = _surface;
98- if (currentSurface != null ) {
99- final bool isSameSize = size.width == currentSurface.width () &&
100- size.height == currentSurface.height ();
101- if (isSameSize) {
102- // The existing surface is still reusable.
103- return ;
104- }
99+ if (size == _currentSize) {
100+ // The existing surface is still reusable.
101+ return ;
105102 }
106103
107- currentSurface? .dispose ();
104+ _currentSize = size;
105+ _surface? .dispose ();
108106 _surface = null ;
109107 htmlElement? .remove ();
110108 htmlElement = null ;
@@ -113,14 +111,28 @@ class Surface {
113111 _surface = _wrapHtmlCanvas (size);
114112 }
115113
116- CkSurface _wrapHtmlCanvas (ui.Size size) {
117- final ui.Size logicalSize = size / ui.window.devicePixelRatio;
114+ CkSurface _wrapHtmlCanvas (ui.Size physicalSize) {
115+ // If `physicalSize` is not precise, use a slightly bigger canvas. This way
116+ // we ensure that the rendred picture covers the entire browser window.
117+ final int pixelWidth = physicalSize.width.ceil ();
118+ final int pixelHeight = physicalSize.height.ceil ();
118119 final html.CanvasElement htmlCanvas = html.CanvasElement (
119- width: size.width.ceil (), height: size.height.ceil ());
120+ width: pixelWidth,
121+ height: pixelHeight,
122+ );
123+
124+ // The logical size of the canvas is not based on the size of the window
125+ // but on the size of the canvas, which, due to `ceil()` above, may not be
126+ // the same as the window. We do not round/floor/ceil the logical size as
127+ // CSS pixels can contain more than one physical pixel and therefore to
128+ // match the size of the window precisely we use the most precise floating
129+ // point value we can get.
130+ final double logicalWidth = pixelWidth / ui.window.devicePixelRatio;
131+ final double logicalHeight = pixelHeight / ui.window.devicePixelRatio;
120132 htmlCanvas.style
121133 ..position = 'absolute'
122- ..width = '${logicalSize . width . ceil () }px'
123- ..height = '${logicalSize . height . ceil () }px' ;
134+ ..width = '${logicalWidth }px'
135+ ..height = '${logicalHeight }px' ;
124136
125137 htmlElement = htmlCanvas;
126138 if (webGLVersion == - 1 || canvasKitForceCpuOnly) {
@@ -153,8 +165,8 @@ class Surface {
153165
154166 SkSurface ? skSurface = canvasKit.MakeOnScreenGLSurface (
155167 _grContext! ,
156- size.width ,
157- size.height ,
168+ pixelWidth ,
169+ pixelHeight ,
158170 SkColorSpaceSRGB ,
159171 );
160172
0 commit comments