@@ -66,6 +66,7 @@ export class TextureAtlas implements ITextureAtlas {
6666
6767 // The set of atlas pages that can be written to
6868 private _activePages : AtlasPage [ ] = [ ] ;
69+ private _overflowSizePage : AtlasPage | undefined ;
6970
7071 private _tmpCanvas : HTMLCanvasElement ;
7172 // A temporary context that glyphs are drawn to before being transfered to the atlas.
@@ -431,7 +432,7 @@ export class TextureAtlas implements ITextureAtlas {
431432 // Allow 1 cell width per character, with a minimum of 2 (CJK), plus some padding. This is used
432433 // to draw the glyph to the canvas as well as to restrict the bounding box search to ensure
433434 // giant ligatures (eg. =====>) don't impact overall performance.
434- const allowedWidth = Math . min ( this . _config . deviceCellWidth * Math . max ( chars . length , 2 ) + TMP_CANVAS_GLYPH_PADDING * 2 , this . _textureSize ) ;
435+ const allowedWidth = Math . min ( this . _config . deviceCellWidth * Math . max ( chars . length , 2 ) + TMP_CANVAS_GLYPH_PADDING * 2 , this . _config . deviceMaxTextureSize ) ;
435436 if ( this . _tmpCanvas . width < allowedWidth ) {
436437 this . _tmpCanvas . width = allowedWidth ;
437438 }
@@ -772,6 +773,27 @@ export class TextureAtlas implements ITextureAtlas {
772773 }
773774 }
774775
776+ // Create a new page for oversized glyphs as they come up
777+ if ( rasterizedGlyph . size . x > this . _textureSize ) {
778+ if ( ! this . _overflowSizePage ) {
779+ this . _overflowSizePage = new AtlasPage ( this . _document , this . _config . deviceMaxTextureSize ) ;
780+ this . pages . push ( this . _overflowSizePage ) ;
781+
782+ // Request the model to be cleared to refresh all texture pages.
783+ this . _requestClearModel = true ;
784+ this . _onAddTextureAtlasCanvas . fire ( this . _overflowSizePage . canvas ) ;
785+ }
786+ activePage = this . _overflowSizePage ;
787+ activeRow = this . _overflowSizePage . currentRow ;
788+ // Move to next row if necessary
789+ if ( activeRow . x + rasterizedGlyph . size . x >= activePage . canvas . width ) {
790+ activeRow . x = 0 ;
791+ activeRow . y += activeRow . height ;
792+ activeRow . height = 0 ;
793+ }
794+ break ;
795+ }
796+
775797 // Create a new page if too much vertical space would be wasted or there is not enough room
776798 // left in the page. The previous active row will become fixed in the process as it now has a
777799 // fixed height
@@ -782,6 +804,7 @@ export class TextureAtlas implements ITextureAtlas {
782804 if ( activePage . currentRow . y + activePage . currentRow . height + rasterizedGlyph . size . y >= activePage . canvas . height ) {
783805 // Find the first page with room to create the new row on
784806 let candidatePage : AtlasPage | undefined ;
807+
785808 for ( const p of this . _activePages ) {
786809 if ( p . currentRow . y + p . currentRow . height + rasterizedGlyph . size . y < p . canvas . height ) {
787810 candidatePage = p ;
0 commit comments