@@ -10,7 +10,6 @@ import {
1010 getIfcContribution ,
1111 createIfcShapedItems ,
1212 createIfcLineboxes ,
13- positionIfcItems ,
1413 sliceIfcRenderText ,
1514 collapseWhitespace
1615} from './layout-text.ts' ;
@@ -832,16 +831,14 @@ export class BlockContainerOfInlines extends BlockContainerBase {
832831 text : string ;
833832 buffer : AllocatedUint16Array ;
834833 items : ShapedItem [ ] ;
835- lineboxes : Linebox [ ] ;
836- fragments : Map < Inline , InlineFragment [ ] > ;
834+ fragments : InlineFragment [ ] ;
837835
838836 constructor ( style : Style , attrs : number ) {
839837 super ( style , attrs ) ;
840838 this . text = '' ;
841839 this . buffer = EmptyBuffer ;
842840 this . items = [ ] ;
843- this . lineboxes = [ ] ;
844- this . fragments = new Map ( ) ;
841+ this . fragments = [ ] ;
845842 }
846843
847844 prelayoutPostorder ( layout : Layout , ctx : PrelayoutContext ) {
@@ -851,12 +848,12 @@ export class BlockContainerOfInlines extends BlockContainerBase {
851848 this . buffer . destroy ( ) ;
852849 this . buffer = createIfcBuffer ( this . text ) ;
853850 this . items = createIfcShapedItems ( layout , this , inline ) ;
854- this . fragments . clear ( ) ;
851+ this . fragments = [ ] ;
855852 }
856853 }
857854
858855 positionItemsPostlayout ( layout : Layout ) {
859- const inlineShifts : Map < Inline , { dx : number ; dy : number } > = new Map ( ) ;
856+ const inlineShifts : Map < number , { dx : number ; dy : number } > = new Map ( ) ;
860857 const parents : Inline [ ] = [ ] ;
861858 const contentArea = this . getContentArea ( ) ;
862859 const rootInline = layout . tree [ this . treeStart + 1 ] ;
@@ -876,7 +873,7 @@ export class BlockContainerOfInlines extends BlockContainerBase {
876873 dy += box . getRelativeVerticalShift ( containingBlock ) ;
877874 }
878875
879- inlineShifts . set ( box , { dx, dy} ) ;
876+ inlineShifts . set ( box . treeStart , { dx, dy} ) ;
880877 parents . push ( box ) ;
881878 } else {
882879 if ( box . isBox ( ) ) i = box . treeFinal ;
@@ -912,14 +909,11 @@ export class BlockContainerOfInlines extends BlockContainerBase {
912909 }
913910 }
914911
915- for ( const [ inline , fragments ] of this . fragments ) {
916- const { dx, dy} = inlineShifts . get ( inline ) ! ;
917-
918- for ( const fragment of fragments ) {
919- fragment . blockOffset += contentArea . y + dy ;
920- fragment . start += contentArea . x + dx ;
921- fragment . end += contentArea . x + dx ;
922- }
912+ for ( const fragment of this . fragments ) {
913+ const { dx, dy} = inlineShifts . get ( fragment . treeIndex ) ! ;
914+ fragment . blockOffset += contentArea . y + dy ;
915+ fragment . left += contentArea . x + dx ;
916+ fragment . right += contentArea . x + dx ;
923917 }
924918 }
925919
@@ -955,15 +949,6 @@ export class BlockContainerOfInlines extends BlockContainerBase {
955949 return sliceIfcRenderText ( layout , this , item , start , end ) ;
956950 }
957951
958- getLineboxHeight ( ) {
959- if ( this . lineboxes . length ) {
960- const line = this . lineboxes . at ( - 1 ) ! ;
961- return line . blockOffset + line . height ( ) ;
962- } else {
963- return 0 ;
964- }
965- }
966-
967952 shouldLayoutContent ( layout : Layout ) {
968953 const inline = layout . tree [ this . treeStart + 1 ] ;
969954 if ( ! inline . isInline ( ) ) throw new Error ( 'Assertion failed' ) ;
@@ -977,11 +962,10 @@ export class BlockContainerOfInlines extends BlockContainerBase {
977962 const containingBlock = this . getContainingBlock ( ) ;
978963 const blockSize = this . style . getBlockSize ( containingBlock ) ;
979964 if ( this . shouldLayoutContent ( layout ) ) {
980- this . lineboxes = createIfcLineboxes ( layout , this , ctx ) ;
981- positionIfcItems ( layout , this ) ;
982- }
983- if ( blockSize === 'auto' ) {
984- this . setBlockSize ( containingBlock , this . getLineboxHeight ( ) ) ;
965+ const ifc = createIfcLineboxes ( layout , this , ctx ) ;
966+ if ( blockSize === 'auto' ) {
967+ this . setBlockSize ( containingBlock , ifc . blockOffset - ifc . bfc . cbBlockStart ) ;
968+ }
985969 }
986970 }
987971}
@@ -1276,7 +1260,6 @@ export class Break extends TreeNode {
12761260}
12771261
12781262export class Inline extends Box {
1279- public nshaped : number ;
12801263 public metrics : InlineMetrics ;
12811264 public textStart : number ;
12821265 public textEnd : number ;
@@ -1287,13 +1270,11 @@ export class Inline extends Box {
12871270 this . textEnd = 0 ;
12881271 this . treeStart = 0 ;
12891272 this . treeFinal = 0 ;
1290- this . nshaped = 0 ;
12911273 this . metrics = EmptyInlineMetrics ;
12921274 }
12931275
12941276 prelayoutPreorder ( ctx : PrelayoutContext ) {
12951277 super . prelayoutPreorder ( ctx ) ;
1296- this . nshaped = 0 ;
12971278 this . metrics = getFontMetrics ( this ) ;
12981279 }
12991280
@@ -1372,22 +1353,20 @@ export class Inline extends Box {
13721353 return this . style . hasLineRightGap ( containingBlock ) ;
13731354 }
13741355
1375- getInlineSideSize ( containingBlock : BoxArea , side : 'pre' | 'post' ) {
1356+ getInlineStartSize ( containingBlock : BoxArea ) {
13761357 const direction = this . getDirectionAsParticipant ( containingBlock ) ;
1377- if (
1378- direction === 'ltr' && side === 'pre' ||
1379- direction === 'rtl' && side === 'post'
1380- ) {
1381- const marginLineLeft = this . style . getMarginLineLeft ( containingBlock ) ;
1382- return ( marginLineLeft === 'auto' ? 0 : marginLineLeft )
1383- + this . style . getBorderLineLeftWidth ( containingBlock )
1384- + this . style . getPaddingLineLeft ( containingBlock ) ;
1385- } else {
1386- const marginLineRight = this . style . getMarginLineRight ( containingBlock ) ;
1387- return ( marginLineRight === 'auto' ? 0 : marginLineRight )
1388- + this . style . getBorderLineRightWidth ( containingBlock )
1389- + this . style . getPaddingLineRight ( containingBlock ) ;
1390- }
1358+ const marginStart = this . style . getMarginInlineStart ( containingBlock , direction ) ;
1359+ return ( marginStart === 'auto' ? 0 : marginStart )
1360+ + this . style . getBorderInlineStartWidth ( containingBlock , direction )
1361+ + this . style . getPaddingInlineStart ( containingBlock , direction ) ;
1362+ }
1363+
1364+ getInlineEndSize ( containingBlock : BoxArea ) {
1365+ const direction = this . getDirectionAsParticipant ( containingBlock ) ;
1366+ const marginEnd = this . style . getMarginInlineEnd ( containingBlock , direction ) ;
1367+ return ( marginEnd === 'auto' ? 0 : marginEnd )
1368+ + this . style . getBorderInlineEndWidth ( containingBlock , direction )
1369+ + this . style . getPaddingInlineEnd ( containingBlock , direction ) ;
13911370 }
13921371
13931372 isInline ( ) : this is Inline {
@@ -1521,9 +1500,9 @@ export class ReplacedBox extends FormattingBox {
15211500export type InlineLevel = Inline | Run | Break | BlockContainer | ReplacedBox ;
15221501
15231502type InlineIteratorBuffered = { state : 'pre' | 'post' , item : Inline }
1524- | { state : 'text' , item : Run }
1503+ | { state : 'text' , item : Run , index : number }
15251504 | { state : 'box' , item : BlockLevel }
1526- | { state : 'break' }
1505+ | { state : 'break' , index : number }
15271506 | { state : 'breakop' } ;
15281507
15291508type InlineIteratorValue = InlineIteratorBuffered | { state : 'breakspot' } ;
@@ -1566,6 +1545,9 @@ export function inlineIteratorStateNext(state: InlineIteratorState) {
15661545 state . breakspotIndex = 0 ;
15671546 state . isInlineBlock = false ;
15681547
1548+ // This body of this loop consumes (pre | post)* atomic? post*,
1549+ // where atomic is a <br>, an inline-block, or a float, and pre/post
1550+ // are sides of an inline.
15691551 while ( state . index <= state . block . treeFinal && ! foundAtomic ) {
15701552 const item = state . layout . tree [ state . index ] ;
15711553
@@ -1577,9 +1559,9 @@ export function inlineIteratorStateNext(state: InlineIteratorState) {
15771559 state . minlevel = state . parents . length ;
15781560
15791561 if ( item . isRun ( ) ) {
1580- state . buffered . push ( { state : 'text' , item} ) ;
1562+ state . buffered . push ( { state : 'text' , item, index : state . index } ) ;
15811563 } else if ( item . isBreak ( ) ) {
1582- state . buffered . push ( { state : 'break' } ) ;
1564+ state . buffered . push ( { state : 'break' , index : state . index } ) ;
15831565 } else {
15841566 if ( item . isFloat ( ) ) {
15851567 state . buffered . push ( { state : 'box' , item} ) ;
0 commit comments