Fix math spacing, delimiters, radicals, and script fractions#156
Fix math spacing, delimiters, radicals, and script fractions#156AshtonSBradley wants to merge 3 commits intoKolaru:masterfrom
Conversation
|
Hi @Kolaru This tests quite a lot of corner cases (coverage inspired by other font packages) and took quite a lot of manual iteration loops to converge on the current visual regression state where all fonts look pretty consistent and not obviously broken. Quite a few things were just broken for some fonts, or used weird glyphs. I also went to a fair bit of effort to make this a compact change to code. I hope it is useful to close a bunch of issues all at once. |
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #156 +/- ##
==========================================
+ Coverage 79.93% 82.91% +2.97%
==========================================
Files 10 10
Lines 658 796 +138
==========================================
+ Hits 526 660 +134
- Misses 132 136 +4 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
|
Looks like the main change in the ReferenceTests is the integral symbol become smaller. A minor shift in space between top of characters and bottom of square root vinculum. The rest look either unchanged or a little better to my eye. Expansion of the package ReferenceTest to improve coverage could also be a useful direction, but I didn't go there in this PR yet. |
Fix math spacing, delimiters, radicals, and script fractions
Summary
This PR improves several related math layout regressions that show up in labels, scripts, and multi-font rendering:
f(t),g(x),(f)x, andη(t).LayoutState.script_level, allowing script-style fractions and operator spacing to be tuned separately from top-level math.\left(...\right)_0and\left(...\right)^{1/4}.x^{\frac{1}{1+2}}andx_{\frac{1}{1+2}}.\langle,\rangle, vertical bars, and integrals.\int.Closes #9.
Closes #95.
Closes #129.
Closes #142.
Explanation
The main layout change is to carry script depth in
LayoutState. Decorated expressions now lay out their lower and upper scripts in an incremented script state, which lets nested fractions and spaced operators use script-style rules without changing top-level layout. Tall cores use ink bounds to place scripts relative to the visible shape, reducing the over-high subscripts and over-low superscripts around scaled delimiters.Italic/upright spacing still uses glyph ink bounds rather than only advance widths. Lower-case Greek symbols are marked as slanted for layout purposes, including symbols loaded through a font family's special-character path, so Greek letters participate in the same boundary correction as italic Latin letters.
Delimiter and radical rendering now falls back to the default math font when the selected font lacks a usable math glyph or has text-shaped delimiter glyphs. This keeps
\langle...\rangle, vertical bars, square roots, and integrals visible and consistent across NewComputerModern, TeXGyreHeros, TeXGyrePagella, and LucioleMath. The NewComputerModern\intmapping is corrected to use the normal inline integral, avoiding accidental delimiter over-scaling around a display-sized integral.The parser change is small:
manual_texexprnow treats delimiter and punctuation tuple heads as leaves, matchingisleaf. That keeps layout code from needing to normalize parser/test helper artifacts.Visual Regression
This PR uses an extensive visual regression sheet as part of the debugging workflow, not just as a final artifact. MathTeX layout bugs are often coupled: fixing a subscript can shift tall delimiters, changing a missing glyph fallback can expose radical or fraction placement issues, and behavior can differ substantially across font families. A broad visual sheet made it possible to inspect many representative expressions at once, catch second-order regressions quickly, and iterate on the small numerical layout constants with the same before/after context each time.
The generated multi-font visual regression sheet compares this branch against a clean baseline worktree. Blue marks the current branch, red marks the baseline. The cases intentionally cover issue-specific examples plus neighboring stress cases: italic/upright boundaries, lower-case Greek, nested scripts, primes, roman text, operators, delimiters, fractions, radicals, integrals, and nested expressions across NewComputerModern, TeXGyreHeros, TeXGyrePagella, and LucioleMath.
Open the full-size visual regression PNG
Tests
julia --project=/Users/braas09p/Dropbox/Julia/Dev/MathTeXEngine.jl -e 'using Pkg; Pkg.test()'julia --project=@runic -e 'using Runic; foreach(file -> Runic.format_file(file; inplace = true), files)'was run on the touched Julia files, then formatter-only churn outside the PR changes was trimmed back.Notes
This does not attempt a full OpenType MATH-table implementation. The visual sheet includes related cases from #93, #105, #110, #126, and PR #151 so they can be inspected, but this PR should not claim to fully close all of those issues.
This partially overlaps #61 by improving unary/operator spacing, but #61 also discusses superscript vertical placement, so I would not close it from this PR alone.
No new dependencies are added.
No public exports are added.