@@ -113,14 +113,28 @@ class Surface {
113113 _surface = _wrapHtmlCanvas (size);
114114 }
115115
116- CkSurface _wrapHtmlCanvas (ui.Size size) {
117- final ui.Size logicalSize = size / ui.window.devicePixelRatio;
116+ CkSurface _wrapHtmlCanvas (ui.Size physicalSize) {
117+ // If `physicalSize` is not precise, use a slightly bigger canvas. This way
118+ // we ensure that the rendred picture covers the entire browser window.
119+ final int pixelWidth = physicalSize.width.ceil ();
120+ final int pixelHeight = physicalSize.height.ceil ();
118121 final html.CanvasElement htmlCanvas = html.CanvasElement (
119- width: size.width.ceil (), height: size.height.ceil ());
122+ width: pixelWidth,
123+ height: pixelHeight,
124+ );
125+
126+ // The logical size of the canvas is not based on the size of the window
127+ // but on the size of the canvas, which, due to `ceil()` above, may not be
128+ // the same as the window. We do not round/floor/ceil the logical size as
129+ // CSS pixels can contain more than one physical pixel and therefore to
130+ // match the size of the window precisely we use the most precise floating
131+ // point value we can get.
132+ final double logicalWidth = pixelWidth / ui.window.devicePixelRatio;
133+ final double logicalHeight = pixelHeight / ui.window.devicePixelRatio;
120134 htmlCanvas.style
121135 ..position = 'absolute'
122- ..width = '${logicalSize . width . ceil () }px'
123- ..height = '${logicalSize . height . ceil () }px' ;
136+ ..width = '${logicalWidth }px'
137+ ..height = '${logicalHeight }px' ;
124138
125139 htmlElement = htmlCanvas;
126140 if (webGLVersion == - 1 || canvasKitForceCpuOnly) {
@@ -153,8 +167,8 @@ class Surface {
153167
154168 SkSurface ? skSurface = canvasKit.MakeOnScreenGLSurface (
155169 _grContext! ,
156- size.width ,
157- size.height ,
170+ pixelWidth ,
171+ pixelHeight ,
158172 SkColorSpaceSRGB ,
159173 );
160174
0 commit comments