typography and documents: an exported formula frames its outlined text; rendered modes have no source selection
This commit is contained in:
4 files changed
+42
-9
No files matched your search
@@ -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();
|
||||
};
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
@@ -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:?}");
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user