typography and documents: an exported formula frames its outlined text; rendered modes have no source selection
CI / platforms (windows-latest) (push) Failing after 8s
CI / site (push) Successful in 22s
CI / crate (push) Failing after 11m54s
CI / platforms (ubuntu-24.04) (push) Canceled after 0s

This commit is contained in:
ZacharyZhang-NY committed 2026-10-12 11:15:52 -04:00
1 parent 3bbbd05f38
commit 8234fcdeb2
4 files changed
+42 -9

No files matched your search

+4
View File
@@ -31,6 +31,10 @@ impl MarkdownDocument {
/// The selected Markdown: the source's, or the open block's.
pub fn selected(&self, cx: &App) -> String {
let Some(open) = &self.open else {
// Rendered modes show no source selection.
if !matches!(self.mode, MarkdownMode::Source | MarkdownMode::Split) {
return String::new();
}
let editor = self.editor.read(cx);
return editor.text()[editor.primary().range()].to_string();
};
+8 -4
View File
@@ -211,10 +211,14 @@ fn the_selection_reads_in_source_and_in_an_open_block(cx: &mut TestAppContext) {
document.read_with(cx, |document, cx| document.selected(cx)),
"One"
);
document.update_in(cx, |document, window, cx| {
document.set_mode(MarkdownMode::Visual, window, cx)
});
frames(cx);
for mode in [MarkdownMode::Preview, MarkdownMode::Visual] {
document.update_in(cx, |document, window, cx| {
document.set_mode(mode, window, cx)
});
frames(cx);
let selected = document.read_with(cx, |document, cx| document.selected(cx));
assert_eq!(selected, "", "{mode:?} shows no source selection");
}
super::type_in(&document, Some(1), None, cx);
document.update(cx, |document, cx| {
let open = document.open.as_ref().expect("a block is open");
+12 -5
View File
@@ -125,13 +125,20 @@ pub fn formula_svg(source: &str, display: bool) -> Result<String, MathError> {
font: 1600,
scale: 100,
};
let (svg, width, height) = laid(&formula)?;
// RaTeX writes text where it has no outline.
let (svg, _) = svg(&formula)?;
crate::documents::flatten(&svg).map_err(MathError::said)
let outlined = crate::documents::flatten(&svg).map_err(MathError::said)?;
framed(&outlined, width, height).map(|(svg, _)| svg)
}
/// The formula as outlined SVG holding all ink; its size.
fn svg(formula: &Formula) -> Result<(String, Size<Pixels>), MathError> {
let (svg, width, height) = laid(formula)?;
framed(&svg, width, height)
}
/// RaTeX's SVG and the layout box's width and height.
fn laid(formula: &Formula) -> Result<(String, f32, f32), MathError> {
let ast = parsed(&formula.source)?;
let [r, g, b, a] = formula
.rgba
@@ -144,7 +151,7 @@ fn svg(formula: &Formula) -> Result<(String, Size<Pixels>), MathError> {
})
.with_color(Color::new(r, g, b, a));
let font = f64::from(formula.font) / 100.0;
let laid = guarded(|| {
let typeset = guarded(|| {
let list = to_display_list(&layout(&ast, &options));
let svg = render_to_svg(
&list,
@@ -158,8 +165,8 @@ fn svg(formula: &Formula) -> Result<(String, Size<Pixels>), MathError> {
);
(list.width * font, (list.height + list.depth) * font, svg)
})?;
let (width, height, svg) = laid;
framed(&svg, width as f32, height as f32)
let (width, height, svg) = typeset;
Ok((svg, width as f32, height as f32))
}
/// Runs RaTeX's layout; a panic becomes an error.
+18
View File
@@ -193,3 +193,21 @@ fn an_exported_formula_outlines_its_text_or_says_why() {
let why = formula_svg("\\text{\u{F0000}}", false).expect_err("no font");
assert!(why.to_string().contains("font"), "{why}");
}
#[test]
fn an_exported_formula_frames_its_outlined_text() {
// Wide or tall faces from the system, where fonts have them.
for source in [r"\text{한글}", r"\text{𓀀} + x"] {
let Ok(svg) = formula_svg(source, false) else {
continue;
};
let tree =
usvg::Tree::from_data(svg.as_bytes(), &usvg::Options::default()).expect("parses");
let (ink, shape) = (tree.root().abs_stroke_bounding_box(), tree.size());
let inside = ink.left() >= -0.01
&& ink.top() >= -0.01
&& ink.right() <= shape.width() + 0.01
&& ink.bottom() <= shape.height() + 0.01;
assert!(inside, "{source}: {ink:?} in {shape:?}");
}
}