@@ -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.
@@ -75,8 +76,6 @@ export class TextureAtlas implements ITextureAtlas {
7576 private _workAttributeData : AttributeData = new AttributeData ( ) ;
7677
7778 private _textureSize : number = 512 ;
78- // TODO: Use actual value
79- private _deviceMaxTextureSize : number = 2048 ;
8079
8180 public static maxAtlasPages : number | undefined ;
8281 public static maxTextureSize : number | undefined ;
@@ -433,7 +432,7 @@ export class TextureAtlas implements ITextureAtlas {
433432 // Allow 1 cell width per character, with a minimum of 2 (CJK), plus some padding. This is used
434433 // to draw the glyph to the canvas as well as to restrict the bounding box search to ensure
435434 // giant ligatures (eg. =====>) don't impact overall performance.
436- const allowedWidth = Math . min ( this . _config . deviceCellWidth * Math . max ( chars . length , 2 ) + TMP_CANVAS_GLYPH_PADDING * 2 , this . _deviceMaxTextureSize ) ;
435+ const allowedWidth = Math . min ( this . _config . deviceCellWidth * Math . max ( chars . length , 2 ) + TMP_CANVAS_GLYPH_PADDING * 2 , this . _config . deviceMaxTextureSize ) ;
437436 if ( this . _tmpCanvas . width < allowedWidth ) {
438437 this . _tmpCanvas . width = allowedWidth ;
439438 }
@@ -774,19 +773,24 @@ export class TextureAtlas implements ITextureAtlas {
774773 }
775774 }
776775
777- // TODO: Move below after page merging to ensure page limit isn't hit
778776 // Create a new page for oversized glyphs as they come up
779777 if ( rasterizedGlyph . size . x > this . _textureSize ) {
780- // TODO: Reuse a single oversized glyphs page
781- const newPage = new AtlasPage ( this . _document , this . _deviceMaxTextureSize ) ;
782- this . pages . push ( newPage ) ;
778+ if ( ! this . _overflowSizePage ) {
779+ this . _overflowSizePage = new AtlasPage ( this . _document , this . _config . deviceMaxTextureSize ) ;
780+ this . pages . push ( this . _overflowSizePage ) ;
783781
784- // Request the model to be cleared to refresh all texture pages.
785- this . _requestClearModel = true ;
786- this . _onAddTextureAtlasCanvas . fire ( newPage . canvas ) ;
787-
788- newPage . addGlyph ( rasterizedGlyph ) ;
789- activePage . fixedRows . push ( newPage . currentRow ) ;
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+ }
790794 break ;
791795 }
792796
@@ -800,6 +804,7 @@ export class TextureAtlas implements ITextureAtlas {
800804 if ( activePage . currentRow . y + activePage . currentRow . height + rasterizedGlyph . size . y >= activePage . canvas . height ) {
801805 // Find the first page with room to create the new row on
802806 let candidatePage : AtlasPage | undefined ;
807+
803808 for ( const p of this . _activePages ) {
804809 if ( p . currentRow . y + p . currentRow . height + rasterizedGlyph . size . y < p . canvas . height ) {
805810 candidatePage = p ;
0 commit comments