mirror of
https://github.com/storytold/pdfcraft.git
synced 2026-11-06 18:52:36 +00:00
fix(edit): reach one line above the paragraph's top (#3973)
A larger range on the first line of a multi-line paragraph rises from the first line's baseline, not from the old box's bottom, so the reach now extends one pitch above the moved box's top. Name the 1.2 em line floor. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SqmHYx8FiWM5PcsoiErgp9
This commit is contained in:
1 parent
8e5f423d6d
commit
ffa08fa00d
3 files changed
+7
-11
No files matched your search
@@ -375,7 +375,7 @@ pub(crate) struct Reach {
|
||||
|
||||
impl Reach {
|
||||
/// The old box and the moved one, grown to `width` either way (alignment may grow a line left
|
||||
/// or right), down to `rows` lines and up to one `pitch` above its bottom (a larger size); turned text grows by the lines' diagonal every way.
|
||||
/// or right), down to `rows` lines and up one `pitch` above its top (a larger size on the first line, however many lines the old box had); turned text grows by the lines' diagonal every way.
|
||||
/// Unbounded when a number is not finite.
|
||||
pub(crate) fn bounds(&self) -> [f64; 4] {
|
||||
const UNBOUNDED: [f64; 4] = [f64::NEG_INFINITY, f64::NEG_INFINITY, f64::INFINITY, f64::INFINITY];
|
||||
@@ -387,12 +387,7 @@ impl Reach {
|
||||
let rows = f64::from(u32::try_from(self.rows).unwrap_or(u32::MAX));
|
||||
let (width, height) = (self.width.abs(), self.pitch.abs() * rows);
|
||||
let grown = if self.upright {
|
||||
[
|
||||
moved[0].min(moved[2] - width),
|
||||
moved[1].min(moved[3] - height),
|
||||
moved[2].max(moved[0] + width),
|
||||
moved[3].max(moved[1] + self.pitch.abs()),
|
||||
]
|
||||
[moved[0].min(moved[2] - width), moved[1].min(moved[3] - height), moved[2].max(moved[0] + width), moved[3] + self.pitch.abs()]
|
||||
} else {
|
||||
let d = width.hypot(height);
|
||||
[moved[0] - d, moved[1] - d, moved[2] + d, moved[3] + d]
|
||||
|
||||
@@ -4622,13 +4622,13 @@ fn an_ocr_rewrite_goes_on_top_of_paint_over_where_it_lands() {
|
||||
#[test]
|
||||
fn a_rewrites_reach_covers_its_move_width_and_lines() {
|
||||
let reach = |offset, width, rows, upright| crate::Reach { rect: [10.0, 90.0, 30.0, 100.0], offset, width, rows, pitch: 10.0, upright }.bounds();
|
||||
assert_eq!(reach([0.0, 0.0], 20.0, 1, true), [10.0, 90.0, 30.0, 100.0]);
|
||||
assert_eq!(reach([0.0, 0.0], 20.0, 1, true), [10.0, 90.0, 30.0, 110.0]);
|
||||
assert_eq!(reach([5.0, -50.0], 20.0, 1, true), [10.0, 40.0, 35.0, 100.0]);
|
||||
assert_eq!(reach([0.0, 0.0], 50.0, 3, true), [-20.0, 70.0, 60.0, 100.0]);
|
||||
assert_eq!(reach([0.0, 0.0], 50.0, 3, true), [-20.0, 70.0, 60.0, 110.0]);
|
||||
assert_eq!(reach([0.0, 0.0], 30.0, 4, false), [-40.0, 40.0, 80.0, 150.0]);
|
||||
assert_eq!(reach([f64::NAN, 0.0], 20.0, 1, true)[0], f64::NEG_INFINITY);
|
||||
let larger = crate::Reach { rect: [10.0, 90.0, 30.0, 100.0], offset: [0.0, 0.0], width: 20.0, rows: 1, pitch: 24.0, upright: true };
|
||||
assert_eq!(larger.bounds(), [10.0, 76.0, 30.0, 114.0], "a larger size grows the line up as well as down");
|
||||
assert_eq!(larger.bounds(), [10.0, 76.0, 30.0, 124.0], "a larger size grows the line up as well as down");
|
||||
}
|
||||
|
||||
/// Revealed OCR text may have to go on top of the page; a page whose marked content nests too deep
|
||||
|
||||
@@ -825,7 +825,8 @@ pub(crate) fn rewrite_styled_block(
|
||||
let largest =
|
||||
block.lines.iter().filter_map(|i| lines.get(*i)).map(|l| l.size).chain(style.ranges.iter().filter_map(|r| r.size)).fold(first.size, f64::max);
|
||||
// At least one line of the largest glyphs, so a larger range reaches up as far as it draws.
|
||||
let pitch = source_leading.max(row_step(style, largest, source_leading)).max(largest * 1.2);
|
||||
const LINE_EM: f64 = 1.2;
|
||||
let pitch = source_leading.max(row_step(style, largest, source_leading)).max(largest * LINE_EM);
|
||||
let widest = measured.iter().copied().fold(width, f64::max);
|
||||
// This path lays rows out along user-space baselines, so the paragraph is upright here.
|
||||
let reach = crate::Reach { rect: block.rect, offset: [dx, dy], width: widest, rows: rows.len(), pitch, upright: true };
|
||||
|
||||
Reference in new issue
Block a user