1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
//! Pure-arithmetic script-run decision rule, shared by running-prose assembly and table-cell
//! reading order.
//!
//! A sub/superscript sits at a baseline offset from the run it annotates and is drawn in a
//! materially smaller font; both properties are ordinary floats regardless of which domain type
//! (`SegmentData` for prose, `xberg_native_pdf::layout::TextSpan` for table cells) supplied them.
//! This module holds only that float arithmetic. Each caller keeps its own type-specific guards
//! (monospace, semantic role, rotation, finiteness) and geometry accessors, and calls in here for
//! the actual baseline/font-size and forward-gap decisions.
//!
//! ~keep The three constants below are read by every script-run consumer in the crate:
//! `pdf::structure::pipeline` (prose assembly, GH#1617), `pdf::native::table` (structural table
//! cells, GH#1628) and `pdf::table_reconstruct` (word-level table reconstruction, GH#1628). They
//! were duplicated across the first two for one release; keep them here so a threshold cannot be
//! tuned on one path and silently disagree with the others.
/// Largest baseline offset, as a multiple of the larger font size, at which a smaller abutting run
/// still reads as a sub/superscript of its neighbour rather than as the next wrapped line.
///
/// ~keep GH#1617: the five torn pairs on the reproducer sit 0.63--1.07pt off a 11.59pt baseline,
/// i.e. 0.054--0.092 font-sizes, while a wrapped line is separated by a full leading (>= 1.0). The
/// 3x margin either side is why this is expressible as a predicate instead of by widening
/// `pdf::structure::pipeline`'s `INLINE_STYLE_BASELINE_TOLERANCE`, which is read at seven sites
/// there and gates dehyphenation at `spans_visual_line_break`.
pub const SCRIPT_RUN_MAX_BASELINE_FONT_FACTOR: f32 = 0.35;
/// Largest ratio of the smaller run's font size to the larger one's for the pair to read as a
/// sub/superscript.
///
/// ~keep GH#1617: 0.63--0.73 on the reproducer against 1.00 for every ordinary same-size style-run
/// boundary, so a same-size boundary cannot reach this predicate at all.
pub const SCRIPT_RUN_MAX_FONT_SIZE_RATIO: f32 = 0.85;
/// Largest forward gap, as a multiple of the larger font size, between a run's end and an abutting
/// sub/superscript's start.
///
/// ~keep GH#1617: `rated` starts at 211.92 where `P` ends at 211.94 -- scripts abut or overlap
/// their base, so this stays far below the ordinary inline-style forward-gap allowance.
pub const SCRIPT_RUN_MAX_FORWARD_GAP_FONT_FACTOR: f32 = 0.25;
/// Whether a non-zero baseline offset paired with a materially smaller font reads as a
/// sub/superscript relationship.
///
/// `font_size` is the larger of the two runs' font sizes; `smaller_font_size` is the smaller.
/// Deliberately requires a *non-zero* offset — a run at the identical baseline is a same-size
/// style transition, not a script run, and is handled by the caller's own on-baseline path.
pub
/// Whether `next`'s advance-axis start reads as abutting or overlapping `previous`'s extent — the
/// forward-gap half of the sub/superscript decision, independent of the baseline/font-size half.
pub