Replace the cosmic-text path with Parley layout and Swash rasterization, backed by shared glyph-atlas pages. Shaping, editing, rasterization, and glyph rendering move together because they share the text buffer and rendered-glyph types; splitting them further would require a temporary renderer that is immediately removed. This is reconstructed rather than replayed from the extraction history. It also fixes issues found during review: - texture binding changes remain set when an atlas patch follows a new page - pressing an empty field places a caret and accepts input - selection motion delegates collapse behavior to Parley - character deletion follows logical clusters rather than visual neighbors - the unused root-level Swash dependency is omitted Four public-behavior integration tests live in `tests/text_edit.rs`: empty-field input, multibyte IME preedit replacement, UTF-8-safe backspace, and selection replacement. The old twelve-test inline block and implementation-restating cases are omitted. Every added source comment was manually reviewed. Comments that narrated implementation or history were removed; retained comments document cache/rasterization keys, GPU upload constraints, focus representation, bidi geometry, or IME semantics. Known limitation: atlas pages currently grow without eviction. Each page is 4 MiB on CPU and GPU. An arbitrary cap would leave cached rendered-text UVs pointing at reused glyph slots, so bounding this safely needs a later generation/invalidation change. This changes public text types and signatures. GPU glyph rendering is covered by compilation rather than a live-surface test. Verified with: - `cargo fmt --all --check` - `cargo clippy --workspace --all-targets -- -D warnings` - `cargo test --workspace` (four integration tests pass) Cargo still reports inherited future-incompatibility notices for existing wgpu/winit dependencies; there are no current clippy warnings. --------- Co-authored-by: iris <2+iris@noreply.localhost> Reviewed-on: iris/iris#10 Reviewed-by: iris <2+iris@noreply.localhost> Co-authored-by: AIris <4+iris-ai@noreply.localhost>
68 lines
1.6 KiB
Rust
68 lines
1.6 KiB
Rust
use iris::prelude::*;
|
|
|
|
fn editor(text: &str, mode: EditMode) -> (TextEdit, TextData) {
|
|
let view = TextView::new(TextBuffer::new(text), TextAttrs::default(), None);
|
|
(TextEdit::new(view, mode), TextData::default())
|
|
}
|
|
|
|
fn press(edit: &mut TextEditCtx<'_>, x: f32) {
|
|
edit.select(vec2(x, 10.0), vec2(400.0, 200.0), false, false);
|
|
}
|
|
|
|
#[test]
|
|
fn pressing_an_empty_field_places_input() {
|
|
let (mut text, mut data) = editor("", EditMode::SingleLine);
|
|
let mut edit = TextEditCtx {
|
|
text: &mut text,
|
|
data: &mut data,
|
|
};
|
|
|
|
press(&mut edit, 40.0);
|
|
edit.insert("hello");
|
|
|
|
assert_eq!(edit.text.content(), "hello");
|
|
}
|
|
|
|
#[test]
|
|
fn preedit_replaces_the_previous_composition() {
|
|
let (mut text, mut data) = editor("", EditMode::SingleLine);
|
|
let mut edit = TextEditCtx {
|
|
text: &mut text,
|
|
data: &mut data,
|
|
};
|
|
|
|
press(&mut edit, 0.0);
|
|
edit.replace(0, "に");
|
|
edit.replace(1, "日本");
|
|
|
|
assert_eq!(edit.text.content(), "日本");
|
|
}
|
|
|
|
#[test]
|
|
fn backspace_respects_utf8_boundaries() {
|
|
let (mut text, mut data) = editor("aé", EditMode::SingleLine);
|
|
let mut edit = TextEditCtx {
|
|
text: &mut text,
|
|
data: &mut data,
|
|
};
|
|
|
|
press(&mut edit, f32::MAX);
|
|
edit.backspace(false);
|
|
|
|
assert_eq!(edit.text.content(), "a");
|
|
}
|
|
|
|
#[test]
|
|
fn typing_replaces_the_selection() {
|
|
let (mut text, mut data) = editor("hello", EditMode::SingleLine);
|
|
let mut edit = TextEditCtx {
|
|
text: &mut text,
|
|
data: &mut data,
|
|
};
|
|
|
|
edit.select_all();
|
|
edit.insert("goodbye");
|
|
|
|
assert_eq!(edit.text.content(), "goodbye");
|
|
}
|