Files
Marcos Paulo 2e23fd09a1 feat: paste images and files from the clipboard, more image formats, scripts without boxes, code font without ligatures
arboard (image-data) approved for clipboard paste: image bytes become a PNG attachment, copied files inside the vault are linked without copying, outside files are copied; works in Visual and Source. image crate gains jpeg, gif, webp, bmp decoders. Lazy system-font fallbacks for 28 scripts (Bengali, Indic, Thai, CJK, Khmer...) and the math font as last resort. JetBrains Mono copy with calt emptied (SIL OFL, renamed). Big embedded images are shrunk to the texture limit off the UI thread (fixes a crash).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-20 23:59:14 -03:00

27 lines
1.1 KiB
Rust

//! The code font advances every character by the same amount (to the pixel grid): no ligature or pair
//! kerning opens a gap inside a URL or an operator.
use egui::{Color32, Context, FontId, RawInput};
/// x of every glyph of `text` laid out in the monospace family, plus the end of the row.
fn xs(ctx: &Context, text: &str) -> Vec<f32> {
ctx.fonts_mut(|fonts| {
let galley = fonts.layout_no_wrap(text.to_owned(), FontId::monospace(14.0), Color32::WHITE);
let row = &galley.rows[0];
row.glyphs.iter().map(|g| g.pos.x).chain(std::iter::once(row.size.x)).collect()
})
}
#[test]
fn urls_and_operators_keep_one_advance_per_character() {
let ctx = Context::default();
notescraft_ui_egui::fonts::install(&ctx);
ctx.run_ui(RawInput::default(), |_| {}).textures_delta.clear();
for text in ["https://publish.obsidian.md/username/about", "a != b -> c => d // e <!-- f -->"] {
let xs = xs(&ctx, text);
let steps: Vec<f32> = xs.windows(2).map(|w| w[1] - w[0]).collect();
let first = steps[0];
assert!(steps.iter().all(|s| (s - first).abs() <= 1.0), "{text}: uneven advances {steps:?}");
}
}