@@ -89,22 +89,20 @@ class Surface {
89
89
_addedToScene = true ;
90
90
}
91
91
92
+ ui.Size ? _currentSize;
93
+
92
94
void _createOrUpdateSurfaces (ui.Size size) {
93
95
if (size.isEmpty) {
94
96
throw CanvasKitError ('Cannot create surfaces of empty size.' );
95
97
}
96
98
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 ;
105
102
}
106
103
107
- currentSurface? .dispose ();
104
+ _currentSize = size;
105
+ _surface? .dispose ();
108
106
_surface = null ;
109
107
htmlElement? .remove ();
110
108
htmlElement = null ;
@@ -113,14 +111,28 @@ class Surface {
113
111
_surface = _wrapHtmlCanvas (size);
114
112
}
115
113
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 ();
118
119
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;
120
132
htmlCanvas.style
121
133
..position = 'absolute'
122
- ..width = '${logicalSize . width . ceil () }px'
123
- ..height = '${logicalSize . height . ceil () }px' ;
134
+ ..width = '${logicalWidth }px'
135
+ ..height = '${logicalHeight }px' ;
124
136
125
137
htmlElement = htmlCanvas;
126
138
if (webGLVersion == - 1 || canvasKitForceCpuOnly) {
@@ -153,8 +165,8 @@ class Surface {
153
165
154
166
SkSurface ? skSurface = canvasKit.MakeOnScreenGLSurface (
155
167
_grContext! ,
156
- size.width ,
157
- size.height ,
168
+ pixelWidth ,
169
+ pixelHeight ,
158
170
SkColorSpaceSRGB ,
159
171
);
160
172
0 commit comments