@@ -271,6 +271,10 @@ class RenderWebGL extends EventEmitter {
271271
272272 this . on ( RenderConstants . Events . NativeSizeChanged , this . onNativeSizeChanged ) ;
273273
274+ gl . canvas . addEventListener ( 'webglcontextlost' , ( ) => {
275+ this . emit ( RenderConstants . Events . ContextLost ) ;
276+ } ) ;
277+
274278 this . setBackgroundColor ( 1 , 1 , 1 ) ;
275279 this . setStageSize ( xLeft || - 240 , xRight || 240 , yBottom || - 180 , yTop || 180 ) ;
276280 this . resize ( this . _nativeSize [ 0 ] , this . _nativeSize [ 1 ] ) ;
@@ -322,7 +326,9 @@ class RenderWebGL extends EventEmitter {
322326 PenSkin,
323327 SVGSkin,
324328 CanvasMeasurementProvider,
325- Rectangle
329+ Rectangle,
330+ EffectTransform,
331+ ShaderManager
326332 } ;
327333 }
328334
@@ -392,8 +398,8 @@ class RenderWebGL extends EventEmitter {
392398 resize ( pixelsWide , pixelsTall ) {
393399 const { canvas} = this . _gl ;
394400 const pixelRatio = window . devicePixelRatio || 1 ;
395- const newWidth = pixelsWide * pixelRatio ;
396- const newHeight = pixelsTall * pixelRatio ;
401+ const newWidth = Math . round ( pixelsWide * pixelRatio ) ;
402+ const newHeight = Math . round ( pixelsTall * pixelRatio ) ;
397403
398404 // Certain operations, such as moving the color picker, call `resize` once per frame, even though the canvas
399405 // size doesn't change. To avoid unnecessary canvas updates, check that we *really* need to resize the canvas.
@@ -836,10 +842,25 @@ class RenderWebGL extends EventEmitter {
836842 if ( index < endIndex ) {
837843 this . _drawList . splice ( index , 1 ) ;
838844 this . _updateOffsets ( 'delete' , currentLayerGroup . groupIndex ) ;
839- } else {
840- log . warn ( 'Could not destroy drawable that could not be found in layer group.' ) ;
841845 return ;
842846 }
847+
848+ // Certain custom extensions, such as SharkPool Layer Control, thoroughly corrupt internal state
849+ // by rearranging drawables outside the layer they ought to belong to. This breaks a lot of things
850+ // in various ways. One of the things it breaks is the loop above where we try to find the drawable
851+ // by checking where its layer starts and ends. The impact of this corruption is severe enough that
852+ // it's best if we work around it.
853+ index = this . _drawList . indexOf ( drawableID ) ;
854+ if ( index === - 1 ) {
855+ log . warn ( 'Could not destroy drawable that could not be found in draw list.' ) ;
856+ return ;
857+ }
858+ this . _drawList . splice ( index , 1 ) ;
859+ for ( const groupName of this . _groupOrdering ) {
860+ if ( this . _layerGroups [ groupName ] . drawListOffset > index ) {
861+ this . _layerGroups [ groupName ] . drawListOffset -- ;
862+ }
863+ }
843864 }
844865
845866 /**
@@ -2375,6 +2396,7 @@ class RenderWebGL extends EventEmitter {
23752396 * SEURITY CONSIDERATIONS: It is the caller's responsibility to ensure that the @font-face
23762397 * statements do not contain malicious styles.
23772398 * @param {Record<string, string> } customFonts Maps full font families (with fallbacks) to @font-face statements.
2399+ * @returns {Promise<unknown> } Resolves when the fonts are ready to use. Never rejects.
23782400 */
23792401 setCustomFonts ( customFonts ) {
23802402 this . customFonts = customFonts ;
@@ -2401,10 +2423,9 @@ class RenderWebGL extends EventEmitter {
24012423 typeof document . fonts . load === 'function'
24022424 ) {
24032425 const families = Object . keys ( customFonts ) ;
2404- for ( const family of families ) {
2405- document . fonts . load ( `12px ${ family } ` ) ;
2406- }
2426+ return Promise . all ( families . map ( family => document . fonts . load ( `12px ${ family } ` ) . catch ( ( ) => { } ) ) ) ;
24072427 }
2428+ return Promise . resolve ( ) ;
24082429 }
24092430}
24102431
0 commit comments