pdf-codec exposes positioned text runs and I couldn't find a function in it that groups them into lines and words, so each consumer writes its own. A downstream consumer did, and its review turned up two bugs that any hand-rolled version is likely to repeat:
A tolerance for "same baseline" taken from the line's anchor run lets a large heading absorb the small line below it (a 30pt heading swallowed the 9pt line beneath it), and the join then sees a negative gap and drops the space too, producing the run-together text the grouping exists to prevent. The tolerance should come from the smaller of the two runs.
When a run has no advance width, defaulting it to zero makes the previous run's end its own start, so the whole advance reads as a gap and spaces appear inside words ("Com plete ly"). No width should mean no space.
If pdf-codec already does this somewhere I missed (I only looked for line-joining and baseline logic in src), the ask is to expose it and document it; if not, a tested grouper there, with those two cases as tests, would save every consumer from redoing it.
pdf-codec exposes positioned text runs and I couldn't find a function in it that groups them into lines and words, so each consumer writes its own. A downstream consumer did, and its review turned up two bugs that any hand-rolled version is likely to repeat:
A tolerance for "same baseline" taken from the line's anchor run lets a large heading absorb the small line below it (a 30pt heading swallowed the 9pt line beneath it), and the join then sees a negative gap and drops the space too, producing the run-together text the grouping exists to prevent. The tolerance should come from the smaller of the two runs.
When a run has no advance width, defaulting it to zero makes the previous run's end its own start, so the whole advance reads as a gap and spaces appear inside words ("Com plete ly"). No width should mean no space.
If pdf-codec already does this somewhere I missed (I only looked for line-joining and baseline logic in
src), the ask is to expose it and document it; if not, a tested grouper there, with those two cases as tests, would save every consumer from redoing it.