@@ -10,8 +10,10 @@ const LINE_HEIGHT = 19
1010
1111type LayoutModule = typeof import ( './layout.ts' )
1212type LineBreakModule = typeof import ( './line-break.ts' )
13+ type MeasurementModule = typeof import ( './measurement.ts' )
1314type RichInlineModule = typeof import ( './rich-inline.ts' )
1415type AnalysisModule = typeof import ( './analysis.ts' )
16+ type SegmentMetrics = ReturnType < MeasurementModule [ 'getSegmentMetrics' ] >
1517
1618let prepare : LayoutModule [ 'prepare' ]
1719let prepareWithSegments : LayoutModule [ 'prepareWithSegments' ]
@@ -27,6 +29,7 @@ let countPreparedLines: LineBreakModule['countPreparedLines']
2729let measurePreparedLineGeometry : LineBreakModule [ 'measurePreparedLineGeometry' ]
2830let stepPreparedLineGeometry : LineBreakModule [ 'stepPreparedLineGeometry' ]
2931let walkPreparedLines : LineBreakModule [ 'walkPreparedLines' ]
32+ let getSegmentBreakableFitAdvances : MeasurementModule [ 'getSegmentBreakableFitAdvances' ]
3033let prepareRichInline : RichInlineModule [ 'prepareRichInline' ]
3134let materializeRichInlineLineRange : RichInlineModule [ 'materializeRichInlineLineRange' ]
3235let measureRichInlineStats : RichInlineModule [ 'measureRichInlineStats' ]
@@ -262,10 +265,11 @@ class TestOffscreenCanvas {
262265
263266beforeAll ( async ( ) => {
264267 Reflect . set ( globalThis , 'OffscreenCanvas' , TestOffscreenCanvas )
265- const [ analysisMod , mod , lineBreakMod , richInlineMod ] = await Promise . all ( [
268+ const [ analysisMod , mod , lineBreakMod , measurementMod , richInlineMod ] = await Promise . all ( [
266269 import ( './analysis.ts' ) ,
267270 import ( './layout.ts' ) ,
268271 import ( './line-break.ts' ) ,
272+ import ( './measurement.ts' ) ,
269273 import ( './rich-inline.ts' ) ,
270274 ] )
271275 ; ( { isCJK } = analysisMod )
@@ -282,6 +286,7 @@ beforeAll(async () => {
282286 setLocale,
283287 } = mod )
284288 ; ( { countPreparedLines, measurePreparedLineGeometry, stepPreparedLineGeometry, walkPreparedLines } = lineBreakMod )
289+ ; ( { getSegmentBreakableFitAdvances } = measurementMod )
285290 ; ( { prepareRichInline, materializeRichInlineLineRange, measureRichInlineStats, walkRichInlineLineRanges } = richInlineMod )
286291} )
287292
@@ -290,6 +295,25 @@ beforeEach(() => {
290295 clearCache ( )
291296} )
292297
298+ describe ( 'measurement invariants' , ( ) => {
299+ test ( 'breakable fit cache distinguishes fit modes' , ( ) => {
300+ const metrics : SegmentMetrics = { width : 80 , containsCJK : false }
301+ const cache = new Map < string , SegmentMetrics > ( [
302+ [ 'a' , { width : 10 , containsCJK : false } ] ,
303+ [ 'b' , { width : 20 , containsCJK : false } ] ,
304+ [ 'c' , { width : 30 , containsCJK : false } ] ,
305+ [ 'ab' , { width : 35 , containsCJK : false } ] ,
306+ [ 'bc' , { width : 60 , containsCJK : false } ] ,
307+ [ 'abc' , metrics ] ,
308+ ] )
309+
310+ expect ( getSegmentBreakableFitAdvances ( 'abc' , metrics , cache , 0 , 'sum-graphemes' ) ) . toEqual ( [ 10 , 20 , 30 ] )
311+ expect ( getSegmentBreakableFitAdvances ( 'abc' , metrics , cache , 0 , 'pair-context' ) ) . toEqual ( [ 10 , 25 , 40 ] )
312+ expect ( getSegmentBreakableFitAdvances ( 'abc' , metrics , cache , 0 , 'segment-prefixes' ) ) . toEqual ( [ 10 , 25 , 45 ] )
313+ expect ( getSegmentBreakableFitAdvances ( 'abc' , metrics , cache , 0 , 'sum-graphemes' ) ) . toEqual ( [ 10 , 20 , 30 ] )
314+ } )
315+ } )
316+
293317describe ( 'prepare invariants' , ( ) => {
294318 test ( 'whitespace-only input stays empty' , ( ) => {
295319 const prepared = prepare ( ' \t\n ' , FONT )
0 commit comments