Skip to content

Commit 9cf49de

Browse files
committed
Fix browser-like dash breaks in overlong runs
Prefer fitting hyphen-like breakpoints before emergency grapheme breaks in overlong breakable runs, while keeping keep-all behavior on the existing browser-matched path. Refresh browser accuracy and benchmark snapshots. Fixes #89
1 parent bd956e3 commit 9cf49de

10 files changed

Lines changed: 443 additions & 277 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
- Line geometry now preserves browser-style terminal letter spacing, including rich-inline item boundaries and visible soft-hyphen breaks (#171).
1818
- Rich-inline item boundaries no longer overflow the requested width after a forced-progress break (#132).
1919
- The markdown chat demo now drops parsed link URLs unless they resolve to HTTP(S) hrefs (#168).
20+
- Overlong hyphenated runs now prefer browser-like dash breakpoints before falling back to emergency grapheme breaks (#89).
2021

2122
## 0.0.6 - 2026-04-22
2223

accuracy/chrome.json

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@
44
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Safari/537.36",
55
"devicePixelRatio": 2,
66
"viewport": {
7-
"innerWidth": 2560,
8-
"innerHeight": 1227,
9-
"outerWidth": 2560,
10-
"outerHeight": 1314,
7+
"innerWidth": 1512,
8+
"innerHeight": 766,
9+
"outerWidth": 1512,
10+
"outerHeight": 853,
1111
"visualViewportScale": 1
1212
},
1313
"screen": {
14-
"width": 2560,
15-
"height": 1440,
16-
"availWidth": 2560,
17-
"availHeight": 1314,
14+
"width": 1512,
15+
"height": 982,
16+
"availWidth": 1512,
17+
"availHeight": 853,
1818
"colorDepth": 30,
1919
"pixelDepth": 30
2020
}
@@ -76825,5 +76825,5 @@
7682576825
"diff": 0
7682676826
}
7682776827
],
76828-
"requestId": "1778234152524-g3ze5g"
76828+
"requestId": "1778455134064-dzaeth"
7682976829
}

accuracy/firefox.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76825,5 +76825,5 @@
7682576825
"diff": 0
7682676826
}
7682776827
],
76828-
"requestId": "1778234164610-4igphr"
76828+
"requestId": "1778455145984-0ujr0y"
7682976829
}

accuracy/safari.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@
55
"devicePixelRatio": 2,
66
"viewport": {
77
"innerWidth": 1440,
8-
"innerHeight": 2440,
8+
"innerHeight": 763,
99
"outerWidth": 1440,
10-
"outerHeight": 2530,
10+
"outerHeight": 853,
1111
"visualViewportScale": 1
1212
},
1313
"screen": {
14-
"width": 1440,
15-
"height": 2560,
16-
"availWidth": 1440,
17-
"availHeight": 2530,
14+
"width": 1512,
15+
"height": 982,
16+
"availWidth": 1512,
17+
"availHeight": 853,
1818
"colorDepth": 24,
1919
"pixelDepth": 24
2020
}
@@ -76825,5 +76825,5 @@
7682576825
"diff": 0
7682676826
}
7682776827
],
76828-
"requestId": "1778234157599-qh89bv"
76828+
"requestId": "1778455139711-8jiaqg"
7682976829
}

benchmarks/chrome.json

Lines changed: 67 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,22 @@
33
"results": [
44
{
55
"label": "Our library: prepare()",
6-
"ms": 18.100000023841858,
6+
"ms": 17.75,
77
"desc": "One cold 500-text measurement batch"
88
},
99
{
1010
"label": "Our library: layout()",
11-
"ms": 0.14450000047683714,
11+
"ms": 0.14424999952316286,
1212
"desc": "Normalized hot-path throughput per 500-text batch"
1313
},
1414
{
1515
"label": "DOM batch",
16-
"ms": 3.850000023841858,
16+
"ms": 3.9000000953674316,
1717
"desc": "Single 400→300px batch resize: write all, then read all"
1818
},
1919
{
2020
"label": "DOM interleaved",
21-
"ms": 43.5,
21+
"ms": 44.59999990463257,
2222
"desc": "Single 400→300px batch resize: write + read per div"
2323
}
2424
],
@@ -30,7 +30,7 @@
3030
},
3131
{
3232
"label": "Our library: layoutWithLines()",
33-
"ms": 0.053749996423721316,
33+
"ms": 0.0550000011920929,
3434
"desc": "60-text shared-corpus batch across widths 180/220/260px; materializes text lines"
3535
},
3636
{
@@ -40,14 +40,14 @@
4040
},
4141
{
4242
"label": "Our library: layoutNextLine()",
43-
"ms": 0.0449999988079071,
43+
"ms": 0.04375,
4444
"desc": "60-text shared-corpus batch across widths 180/220/260px; streaming line-by-line layout"
4545
}
4646
],
4747
"richInlineResults": [
4848
{
4949
"label": "Our library: measureRichInlineStats()",
50-
"ms": 0.011250001192092896,
50+
"ms": 0.010000002384185792,
5151
"desc": "36 rich-text inline flow shared-corpus texts across widths 180/220/260px; stats only"
5252
},
5353
{
@@ -62,14 +62,14 @@
6262
},
6363
{
6464
"label": "Our library: layoutNextRichInlineLineRange() + materializeRichInlineLineRange()",
65-
"ms": 0.04250000119209289,
65+
"ms": 0.04124999940395355,
6666
"desc": "36 rich-text inline flow shared-corpus texts across widths 180/220/260px; streaming range walk plus per-line materialization"
6767
}
6868
],
6969
"richPreWrapResults": [
7070
{
7171
"label": "Our library: measureLineStats()",
72-
"ms": 0.3049999952316284,
72+
"ms": 0.3074999988079071,
7373
"desc": "12 generated pre-wrap texts with 320 hard-break chunks across widths 220/260/320px; stats only"
7474
},
7575
{
@@ -84,29 +84,29 @@
8484
},
8585
{
8686
"label": "Our library: layoutNextLine()",
87-
"ms": 0.9475000023841857,
87+
"ms": 0.9724999964237213,
8888
"desc": "12 generated pre-wrap texts with 320 hard-break chunks across widths 220/260/320px; streaming line-by-line layout"
8989
}
9090
],
9191
"richLongResults": [
9292
{
9393
"label": "Our library: measureLineStats()",
94-
"ms": 1.6537499994039535,
94+
"ms": 1.6787499994039536,
9595
"desc": "8 Arabic long-form texts across widths 240/300/360px; stats only"
9696
},
9797
{
9898
"label": "Our library: layoutWithLines()",
99-
"ms": 5.550000000000001,
99+
"ms": 5.534999996423721,
100100
"desc": "8 Arabic long-form texts across widths 240/300/360px; materializes text lines"
101101
},
102102
{
103103
"label": "Our library: walkLineRanges()",
104-
"ms": 2.208750000596046,
104+
"ms": 2.23125,
105105
"desc": "8 Arabic long-form texts across widths 240/300/360px; line ranges only, no line text strings"
106106
},
107107
{
108108
"label": "Our library: layoutNextLine()",
109-
"ms": 5.165000000596047,
109+
"ms": 5.313749998807907,
110110
"desc": "8 Arabic long-form texts across widths 240/300/360px; streaming line-by-line layout"
111111
}
112112
],
@@ -121,10 +121,10 @@
121121
"breakableSegments": 0,
122122
"width": 300,
123123
"lineCount": 193,
124-
"analysisMs": 2.3999998569488525,
125-
"measureMs": 4.1000001430511475,
126-
"prepareMs": 6.599999904632568,
127-
"layoutMs": 0.02600000023841858
124+
"analysisMs": 2.5999999046325684,
125+
"measureMs": 4.299999713897705,
126+
"prepareMs": 6.800000190734863,
127+
"layoutMs": 0.02649999976158142
128128
},
129129
{
130130
"id": "ja-rashomon",
@@ -136,10 +136,10 @@
136136
"breakableSegments": 1,
137137
"width": 300,
138138
"lineCount": 380,
139-
"analysisMs": 4.700000047683716,
140-
"measureMs": 7.900000333786011,
141-
"prepareMs": 12.700000047683716,
142-
"layoutMs": 0.04899999976158142
139+
"analysisMs": 4.900000095367432,
140+
"measureMs": 8.5,
141+
"prepareMs": 13.600000143051147,
142+
"layoutMs": 0.049000000953674315
143143
},
144144
{
145145
"id": "ko-unsu-joh-eun-nal",
@@ -151,10 +151,10 @@
151151
"breakableSegments": 0,
152152
"width": 300,
153153
"lineCount": 428,
154-
"analysisMs": 3.3999998569488525,
155-
"measureMs": 8.500000238418579,
156-
"prepareMs": 11.900000095367432,
157-
"layoutMs": 0.0775
154+
"analysisMs": 3.4000000953674316,
155+
"measureMs": 8.499999761581421,
156+
"prepareMs": 12.200000047683716,
157+
"layoutMs": 0.07850000023841858
158158
},
159159
{
160160
"id": "ko-sonagi",
@@ -166,10 +166,10 @@
166166
"breakableSegments": 2,
167167
"width": 300,
168168
"lineCount": 332,
169-
"analysisMs": 2.4000000953674316,
170-
"measureMs": 6.3999998569488525,
171-
"prepareMs": 8.899999856948853,
172-
"layoutMs": 0.05800000071525574
169+
"analysisMs": 2.5999999046325684,
170+
"measureMs": 6.599999904632568,
171+
"prepareMs": 9.099999904632568,
172+
"layoutMs": 0.05950000047683716
173173
},
174174
{
175175
"id": "zh-zhufu",
@@ -181,9 +181,9 @@
181181
"breakableSegments": 4,
182182
"width": 300,
183183
"lineCount": 626,
184-
"analysisMs": 7.200000047683716,
185-
"measureMs": 13.799999952316284,
186-
"prepareMs": 20.799999952316284,
184+
"analysisMs": 7.900000095367432,
185+
"measureMs": 14.399999856948853,
186+
"prepareMs": 22.100000143051147,
187187
"layoutMs": 0.08
188188
},
189189
{
@@ -196,10 +196,10 @@
196196
"breakableSegments": 14,
197197
"width": 300,
198198
"lineCount": 375,
199-
"analysisMs": 4.299999952316284,
200-
"measureMs": 7.3999998569488525,
201-
"prepareMs": 11.799999952316284,
202-
"layoutMs": 0.04700000047683716
199+
"analysisMs": 4.700000047683716,
200+
"measureMs": 8.900000095367432,
201+
"prepareMs": 13.799999952316284,
202+
"layoutMs": 0.04850000023841858
203203
},
204204
{
205205
"id": "th-nithan-vetal-story-1",
@@ -211,10 +211,10 @@
211211
"breakableSegments": 8087,
212212
"width": 300,
213213
"lineCount": 1024,
214-
"analysisMs": 9.800000190734863,
215-
"measureMs": 7.099999666213989,
216-
"prepareMs": 17.5,
217-
"layoutMs": 0.08700000047683716
214+
"analysisMs": 10.399999856948853,
215+
"measureMs": 7.699999809265137,
216+
"prepareMs": 18.299999952316284,
217+
"layoutMs": 0.08950000047683716
218218
},
219219
{
220220
"id": "my-cunning-heron-teacher",
@@ -226,10 +226,10 @@
226226
"breakableSegments": 422,
227227
"width": 300,
228228
"lineCount": 81,
229-
"analysisMs": 0.7000000476837158,
230-
"measureMs": 0.7999999523162842,
231-
"prepareMs": 1.5999999046325684,
232-
"layoutMs": 0.006999999284744263
229+
"analysisMs": 0.7999999523162842,
230+
"measureMs": 0.9999997615814209,
231+
"prepareMs": 1.7999999523162842,
232+
"layoutMs": 0.0070000004768371584
233233
},
234234
{
235235
"id": "my-bad-deeds-return-to-you-teacher",
@@ -242,8 +242,8 @@
242242
"width": 300,
243243
"lineCount": 54,
244244
"analysisMs": 0.5,
245-
"measureMs": 0.5999999046325684,
246-
"prepareMs": 1.0999999046325684,
245+
"measureMs": 0.6000001430511475,
246+
"prepareMs": 1.1999998092651367,
247247
"layoutMs": 0.004500000476837158
248248
},
249249
{
@@ -256,10 +256,10 @@
256256
"breakableSegments": 2922,
257257
"width": 300,
258258
"lineCount": 351,
259-
"analysisMs": 3.6000001430511475,
260-
"measureMs": 3.6999998092651367,
261-
"prepareMs": 7.900000095367432,
262-
"layoutMs": 0.0425
259+
"analysisMs": 3.700000047683716,
260+
"measureMs": 4.1000001430511475,
261+
"prepareMs": 8,
262+
"layoutMs": 0.04350000023841858
263263
},
264264
{
265265
"id": "km-prachum-reuang-preng-khmer-volume-7-stories-1-10",
@@ -271,10 +271,10 @@
271271
"breakableSegments": 4010,
272272
"width": 300,
273273
"lineCount": 591,
274-
"analysisMs": 7.700000047683716,
275-
"measureMs": 4.8999998569488525,
276-
"prepareMs": 13.5,
277-
"layoutMs": 0.08399999976158141
274+
"analysisMs": 8.599999904632568,
275+
"measureMs": 5,
276+
"prepareMs": 13.799999952316284,
277+
"layoutMs": 0.08600000023841858
278278
},
279279
{
280280
"id": "hi-eidgah",
@@ -286,10 +286,10 @@
286286
"breakableSegments": 4089,
287287
"width": 300,
288288
"lineCount": 653,
289-
"analysisMs": 6,
290-
"measureMs": 7.599999904632568,
291-
"prepareMs": 14.299999952316284,
292-
"layoutMs": 0.06900000095367431
289+
"analysisMs": 6.099999904632568,
290+
"measureMs": 8.000000238418579,
291+
"prepareMs": 14.599999904632568,
292+
"layoutMs": 0.07049999952316284
293293
},
294294
{
295295
"id": "synthetic-long-breakable-runs",
@@ -301,10 +301,10 @@
301301
"breakableSegments": 1540,
302302
"width": 300,
303303
"lineCount": 2860,
304-
"analysisMs": 8.600000143051147,
305-
"measureMs": 11.299999952316284,
306-
"prepareMs": 20.5,
307-
"layoutMs": 0.30949999928474425
304+
"analysisMs": 8.599999904632568,
305+
"measureMs": 15.5,
306+
"prepareMs": 24,
307+
"layoutMs": 0.39799999952316284
308308
},
309309
{
310310
"id": "ar-risalat-al-ghufran-part-1",
@@ -316,10 +316,10 @@
316316
"breakableSegments": 18745,
317317
"width": 300,
318318
"lineCount": 2643,
319-
"analysisMs": 26.399999856948853,
320-
"measureMs": 43.90000009536743,
321-
"prepareMs": 70.59999990463257,
322-
"layoutMs": 0.2714999997615814
319+
"analysisMs": 29.100000143051147,
320+
"measureMs": 45,
321+
"prepareMs": 73.10000014305115,
322+
"layoutMs": 0.27700000047683715
323323
}
324324
]
325325
}

0 commit comments

Comments
 (0)