@@ -4,18 +4,22 @@ import {createStyle, Style, EMPTY_STYLE} from './style.ts';
44import {
55 EmptyInlineMetrics ,
66 Linebox ,
7- Paragraph ,
87 Run ,
98 collapseWhitespace ,
10- createEmptyParagraph ,
11- createParagraph ,
12- getFontMetrics
9+ getFontMetrics ,
10+ createIfcBuffer ,
11+ getIfcContribution ,
12+ createIfcShapedItems ,
13+ createIfcLineboxes ,
14+ positionIfcItems ,
15+ sliceIfcRenderText
1316} from './layout-text.ts' ;
1417import { getImage } from './layout-image.ts' ;
1518import { Box , FormattingBox , RenderItem } from './layout-box.ts' ;
1619
17- import type { InlineMetrics } from './layout-text.ts' ;
20+ import type { InlineMetrics , ShapedItem , InlineFragment } from './layout-text.ts' ;
1821import type { BoxArea , PrelayoutContext } from './layout-box.ts' ;
22+ import type { AllocatedUint16Array } from './text-harfbuzz.ts' ;
1923
2024function assumePx ( v : any ) : asserts v is number {
2125 if ( typeof v !== 'number' ) {
@@ -835,7 +839,7 @@ export class BlockContainerOfInlines extends BlockContainerBase {
835839 doTextLayout ( ctx : LayoutContext ) {
836840 const blockSize = this . style . getBlockSize ( this . getContainingBlock ( ) ) ;
837841 this . ifc . doTextLayout ( ctx ) ;
838- if ( blockSize === 'auto' ) this . setBlockSize ( this . ifc . paragraph . getHeight ( ) ) ;
842+ if ( blockSize === 'auto' ) this . setBlockSize ( this . ifc . getLineboxHeight ( ) ) ;
839843 }
840844}
841845
@@ -1040,7 +1044,7 @@ export function layoutContribution(
10401044 }
10411045 } else {
10421046 if ( box . ifc . shouldLayoutContent ( ) ) {
1043- isize = box . ifc . paragraph . contribution ( mode ) ;
1047+ isize = getIfcContribution ( box . ifc , mode ) ;
10441048 }
10451049 }
10461050 }
@@ -1243,17 +1247,28 @@ export class Inline extends Box {
12431247 }
12441248}
12451249
1250+ const EmptyBuffer = {
1251+ array : new Uint16Array ( ) ,
1252+ destroy : ( ) => { }
1253+ } ;
1254+
12461255export class IfcInline extends Inline {
1247- public children : InlineLevel [ ] ;
1248- public text : string ;
1249- public paragraph : Paragraph ;
1256+ children : InlineLevel [ ] ;
1257+ text : string ;
1258+ buffer : AllocatedUint16Array ;
1259+ items : ShapedItem [ ] ;
1260+ lineboxes : Linebox [ ] ;
1261+ fragments : Map < Inline , InlineFragment [ ] > ;
12501262
12511263 constructor ( style : Style , text : string , children : InlineLevel [ ] , attrs : number ) {
12521264 super ( 0 , text . length , style , children , Box . ATTRS . isAnonymous | attrs ) ;
12531265
12541266 this . children = children ;
12551267 this . text = text ;
1256- this . paragraph = createEmptyParagraph ( this ) ;
1268+ this . buffer = EmptyBuffer ;
1269+ this . items = [ ] ;
1270+ this . lineboxes = [ ] ;
1271+ this . fragments = new Map ( ) ;
12571272 }
12581273
12591274 isIfcInline ( ) : this is IfcInline {
@@ -1264,12 +1279,26 @@ export class IfcInline extends Inline {
12641279 return Boolean ( this . bitfield & Box . BITS . enableLogging ) ;
12651280 }
12661281
1282+ sliceRenderText ( item : ShapedItem , start : number , end : number ) {
1283+ return sliceIfcRenderText ( this , item , start , end ) ;
1284+ }
1285+
1286+ getLineboxHeight ( ) {
1287+ if ( this . lineboxes . length ) {
1288+ const line = this . lineboxes . at ( - 1 ) ! ;
1289+ return line . blockOffset + line . height ( ) ;
1290+ } else {
1291+ return 0 ;
1292+ }
1293+ }
1294+
12671295 prelayoutPostorder ( ctx : PrelayoutContext ) {
12681296 if ( this . shouldLayoutContent ( ) ) {
12691297 if ( this . hasCollapsibleWs ( ) ) collapseWhitespace ( this ) ;
1270- this . paragraph . destroy ( ) ;
1271- this . paragraph = createParagraph ( this ) ;
1272- this . paragraph . shape ( ) ;
1298+ this . buffer . destroy ( ) ;
1299+ this . buffer = createIfcBuffer ( this . text ) ;
1300+ this . items = createIfcShapedItems ( this ) ;
1301+ this . fragments . clear ( ) ;
12731302 }
12741303 }
12751304
@@ -1286,10 +1315,10 @@ export class IfcInline extends Inline {
12861315
12871316 if ( 'sentinel' in box ) {
12881317 while (
1289- itemIndex < this . paragraph . items . length &&
1290- this . paragraph . items [ itemIndex ] . offset < box . sentinel . textEnd
1318+ itemIndex < this . items . length &&
1319+ this . items [ itemIndex ] . offset < box . sentinel . textEnd
12911320 ) {
1292- const item = this . paragraph . items [ itemIndex ] ;
1321+ const item = this . items [ itemIndex ] ;
12931322 item . x += containingBlock . x ;
12941323 item . y += containingBlock . y ;
12951324 if ( item . end ( ) > box . sentinel . textStart ) {
@@ -1323,7 +1352,7 @@ export class IfcInline extends Inline {
13231352 }
13241353 }
13251354
1326- for ( const [ inline , fragments ] of this . paragraph . fragments ) {
1355+ for ( const [ inline , fragments ] of this . fragments ) {
13271356 const { dx, dy} = inlineShifts . get ( inline ) ! ;
13281357
13291358 for ( const fragment of fragments ) {
@@ -1335,7 +1364,8 @@ export class IfcInline extends Inline {
13351364 }
13361365
13371366 postlayoutPreorder ( ) {
1338- this . paragraph . destroy ( ) ;
1367+ this . buffer . destroy ( ) ;
1368+ this . buffer = EmptyBuffer ;
13391369 if ( this . shouldLayoutContent ( ) ) {
13401370 this . positionItemsPostlayout ( ) ;
13411371 }
@@ -1351,8 +1381,8 @@ export class IfcInline extends Inline {
13511381
13521382 doTextLayout ( ctx : LayoutContext ) {
13531383 if ( this . shouldLayoutContent ( ) ) {
1354- this . paragraph . createLineboxes ( ctx ) ;
1355- this . paragraph . positionItems ( ctx ) ;
1384+ this . lineboxes = createIfcLineboxes ( this , ctx ) ;
1385+ positionIfcItems ( this ) ;
13561386 }
13571387 }
13581388}
0 commit comments