ElyPDF: text under a covering picture is aimed; a shaky click no longer moves it (P-03)

This commit is contained in:
ZacharyZhang-NY committed 2026-10-09 13:05:48 -04:00
1 parent 04040a2a03
commit 4d8d5a6ef5
6 files changed
+95 -10

No files matched your search

+59 -1
View File
@@ -1,6 +1,6 @@
//! Editing text and objects from the app (C11.3).
use ely_pdf_engine::sample::{Extras, pdf_with};
use ely_pdf_engine::sample::{Extras, one_page, pdf_with};
use gpui::{Entity, Modifiers, MouseButton, TestAppContext, VisualTestContext};
use super::input::over;
@@ -339,3 +339,61 @@ fn a_drag_follows_the_hand_when_the_page_shifts_under_it() {
let rect = cx.update(|_, app| view.read(app).layers[&0].drawn[1].rect);
assert!((rect[0] - 122.0).abs() < 0.5, "moved as far as the hand: {rect:?}");
}
#[test]
fn text_on_a_full_page_picture_aims_at_the_text_and_a_shake_stays_a_click() {
let dir = tempfile::tempdir().expect("a temp dir");
let mut cx = TestAppContext::single();
let path = dir.path().join("scan.pdf");
let extras = Extras { picture: true, backdrop: true, ..Extras::default() };
std::fs::write(&path, pdf_with(&[(612.0, 792.0, &["Hello world"])], &[], &extras)).expect("writes");
let (viewer, cx) = windowed(&mut cx, dir.path(), &[path], true);
let view = shown(cx, &viewer);
settle(cx, |app| view.read(app).room.size.width > gpui::px(100.0));
cx.update(|_, app| view.update(app, |view, cx| {
view.zoom = crate::layout::Zoom::Scale(1.0);
view.set_tool(Tool::Edit, cx)
}));
settle(cx, |app| view.read(app).layers.contains_key(&0));
click(cx, &view, (80.0, 66.0));
assert!(matches!(cx.update(|_, app| view.read(app).aim), Some(Aim::Text { .. })), "the text, not the picture under it");
// A two-pixel wobble on the picture moves nothing.
let from = over(cx, &view, 0, (300.0, 400.0));
cx.simulate_mouse_down(from, MouseButton::Left, Modifiers::none());
let to = from + gpui::point(gpui::px(2.0), gpui::px(0.0));
cx.simulate_mouse_move(to, MouseButton::Left, Modifiers::none());
cx.simulate_mouse_up(to, MouseButton::Left, Modifiers::none());
frames(cx);
assert!(matches!(cx.update(|_, app| view.read(app).aim), Some(Aim::Object { .. })), "the picture is aimed");
assert_eq!(cx.update(|_, app| view.read(app).edited), 0, "and not moved");
}
#[test]
fn a_small_picture_on_text_under_a_page_form_still_aims() {
let dir = tempfile::tempdir().expect("a temp dir");
let mut cx = TestAppContext::single();
let path = dir.path().join("layered.pdf");
// The page-size form comes last, on top of both.
let content = "q 10 0 0 10 80 722 cm /Im1 Do Q BT /F1 18 Tf 72 720 Td (Hello world) Tj ET q /Fm1 Do Q";
let form = "0 0 1 rg 500 50 20 20 re f";
let objects = [
"<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>".to_string(),
format!("<< /Type /XObject /Subtype /Form /BBox [0 0 612 792] /Length {} >>\nstream\n{form}\nendstream", form.len()),
"<< /Type /XObject /Subtype /Image /Width 1 /Height 1 /ColorSpace /DeviceGray /BitsPerComponent 8 /Length 1 >>\nstream\nA\nendstream".to_string(),
];
let page = " /Resources << /Font << /F1 5 0 R >> /XObject << /Fm1 6 0 R /Im1 7 0 R >> >>";
std::fs::write(&path, one_page("", page, content, &objects)).expect("writes");
let (viewer, cx) = windowed(&mut cx, dir.path(), &[path], true);
let view = shown(cx, &viewer);
settle(cx, |app| view.read(app).room.size.width > gpui::px(100.0));
cx.update(|_, app| view.update(app, |view, cx| {
view.zoom = crate::layout::Zoom::Scale(1.0);
view.set_tool(Tool::Edit, cx)
}));
settle(cx, |app| view.read(app).layers.contains_key(&0));
// The picture sits at 80..90 across, 60..70 down.
click(cx, &view, (85.0, 65.0));
assert!(matches!(cx.update(|_, app| view.read(app).aim), Some(Aim::Object { index: 0, .. })), "the small picture");
click(cx, &view, (140.0, 66.0));
assert!(matches!(cx.update(|_, app| view.read(app).aim), Some(Aim::Text { .. })), "the text, not the form around it");
}