Repository navigation
Ink ascent/descent #78
Description
This one is a bit tricky... It was mentioned in #139 and https://github.com/mathml-refresh/mathml/issues/52#issuecomment-514016715 at least. But it needs clear explanation.
When drawing a box, one can distinguish its normal size (the space it occupies) from its "ink" size (smallest enclosing rect for the painted content). For example, a white space has nonzero width/height but an empty ink box.
First the ink size is involved in the OpenType MATH spec when computing vertical gaps [1]. If I'm correct, it is not involved for horizontal placement during layout of math box, so I think we can don't need "ink left/right bearings" and can focus on ink ascent/descent below.
Using CSS baseline concepts, the MathML Core specification defines two new baselines "ink-over baseline" and "ink-under baseline" which delimitate the ink ascent/descent of a box [2]. All the boxes/baselines in the SVG schemas of the spec are drawn with dashes but the ink boxes are suggested with a background.
The status in browser is the following:
- All MathML boxes in Gecko have ink metrics, both vertical and horizontal.
- WebKit does not use ink metrics. For token elements, it calculate box metrics of the text specially [3] which means that it will somewhat work with basic constructions.
- For Blink, @rwlbuis started to implement the concept of the core spec but it's still very experimental and incomplete. It at least somewhat works for text and fractions.
In order to understand this properly, we need a non-trial test case. I uploaded a test case [4] with basic text/fraction/square root examples and the interesting one which is AAA/√CCC (square root as a denominator).
The font is built like this [5]:
- all font ascents/descents are 1em and the "use typo metrics" bit is set.
- Glyphs for A, B, C are 1em squares (respectively 1em ink ascent, 1em ink descent and .5em ink ascent/descent). They are respectively drawn in red, green and blue.
- Glyph for U+221a (radical symbol) is 1em width, 1em ink ascent, 1em ink descent. It can be repeated with 1em overlap to build a glyph assembly.
- fraction and radical rulethickness are 1em
- num/denom min gaps are 1em
- num/denom shifts are 2em
- radical vertical gap is 1em
- radical extra ascender is 2em
Exercise: Deduce the vertical positions of AAA, fraction bar, radical overbar and CCC.
Gecko, WebKit, Blink, XeLaTeX and LuaLaTeX render this last example inconsistently. Analysis is complicated by the fact that there are some unrelated bugs and that I was not able to make XeLaTeX/LuaLaTeX use my custom glyphs for the text.
Two questions for the CG:
(1) Is it important to have this concept of ink ascent/descent for all boxes? Or only male ascent/descent of token elements match the text ink ascent/descent? As I understand the MATH spec, it is important to have it for all boxes...
(2) If it is important, is the MathML Core description correct? For example, is the "radical vertical gap" included in its ink box or not? I guess we should ask Microsoft people about this.
[1] https://docs.microsoft.com/en-us/typography/opentype/spec/math
[2] https://mathml-refresh.github.io/mathml-core/#box-model
[3] https://trac.webkit.org/browser/webkit/trunk/Source/WebCore/css/mathml.css#L19
[4] https://github.com/mathml-refresh/ink-metrics
[5] https://github.com/mathml-refresh/ink-metrics/blob/master/create-font.py
Activity
fred-wang commentedon Aug 23, 2019
@SergeyMalkin Do you know how Microsoft Word would render something equivalent to https://github.com/mathml-refresh/ink-metrics/blob/master/index.tex#L53 or https://github.com/mathml-refresh/ink-metrics/blob/master/index.html#L105 with the font https://github.com/mathml-refresh/ink-metrics/blob/master/ink-ascent-descent-test.otf ? Can you explain how the different fraction / radical parameters are interpreted?
@khaledhosny @jfkthame Do you know why XeLaTeX (and LuaLatex) fails to use my custom glyph for A, B, C in https://github.com/mathml-refresh/ink-metrics/blob/master/index.tex ? Are you able to explain the rendering of https://github.com/mathml-refresh/ink-metrics/blob/master/xelatex.pdf (1.9 specifically).
Thanks!
fred-wang commentedon Aug 23, 2019
From left to right: Gecko, WebKit, Blink, XeLaTeX, LuaLaTeX (as I said I was not able to use my custom glyph in the latex document...)
fred-wang commentedon Aug 23, 2019
Gap between the fraction bar and radical bar seems to be 3em (radical ascender + denominator gap) in Webkit, Blink and LuaLatex. It is only 1em (denominator gap) in Gecko since the radical ascender is not considered part of the msqrt ink box. I don't understand XeLaTeX's result, the gap seems about 3.5em but I don't understand why.
khaledhosny commentedon Aug 23, 2019
They need to be in math ltalic slots (LaTeX by default using ASCII in math mode as shorthand for math italic) or switch math alphabet to uptright roman (
\mathupI think).khaledhosny commentedon Aug 23, 2019
\symupactually,\mathupwitches to the text font (don’t ask me why).fred-wang commentedon Aug 23, 2019
@khaledhosny Thanks. I had tried
\mathupbut that didn't help..Here is the updated result (xelatex: left, lualatex: right). So it seems xelatex uses a 2em gap (radical ascender) > 1em gap (denominator gap).
fred-wang commentedon Aug 23, 2019
Actually xelatex's behavior is weird, even after setting all the gaps/shifts to 0, I still have a 1em gap between the two bars. RadicalExtraAscender does not seem to have any effect.
SergeyMalkin commentedon Aug 26, 2019
This is how Word renders this formula:

I can't immediately explain it, though. Will need a bit more time to give you exact calculations (correct or not) that produced this result.
Thanks,
Sergey
fred-wang commentedon Aug 26, 2019
Thanks, this looks consistent with WebKit, Chromium and LuaLaTeX, except that I don't understand why the "radical vertical gap is" between the blue and radical bar is not 1em. Looking forward to getting more information.
fred-wang commentedon Dec 18, 2019
We discussed this during the two previous meetings and Murray mentioned that Microsoft Word does not distinguish ink VS non-ink boundaries for radicals.
Consensus seems to be that this difference is not fundamental and only Gecko does it. So probably we can remove it and keep the simple form: only use ink extents when calculating the metrics of text-only (only text content without forced line break or soft wrap opportunity) token elements.
fred-wang commentedon Jan 21, 2020
I've committed some changes to remove the distinction between and non-ink metrics for most of the elements (including radical elements mentioned above).
There are some things that I'm not sure.
First, I wonder if we still need to keep a distinction for token elements (rather than claiming the metrics are just the ink ones). For example for MINUS SIGN (U+2212)
<mo>−</mo>whose ink bounding box is typically a thing horizontal bar above the baseline and the "ink descent" is negative. I think negative values still work well with the definition of baseline / alignment. However, the background won't be visible if ink and non-ink boxes match. This is same for any rectangle glyph, which is probably why Gecko keeps the distinction.If we keep the distinction, I believe this has other consequences:
Do we want a distinction for mrow too? For example, the ink bounding boxes of
<mrow><mn>−</mn></mrow>or<mrow><mn>−</mn><mn>−</mn></mrow>should probably be the same as − and −−? But if we distinguish ink and non-ink for token elements, we should probably keep the same distinction for mrow.Similar question for other mrow-like element (merror, mphantom, etc) as well as menclose or mpadded.
Additionally, a nonzero border increases ink size while nonzero margin/padding don't. This means that margin/padding can be used to force different ink and non-ink metrics for any element. This is a bit similar to mpadded but for that element the spec currently always says the ink and non-ink metrics match (even if you add some lspace for example).
5 remaining items
fred-wang commentedon Mar 2, 2022
For completeness, this is how Blink currently renders https://people.igalia.com/fwang/gamma.html:
and how it renders it when using ink metrics for token elements:
Notice that the former contains large vertical gaps, which is definitely not desired. I believe fixing this is more important than having not-very-visible background issue for rectangle glyphs, so I will probably do that for an initial implementation anyway.
This is normally what WebKit does too, but would need to check the details of the implementation to be sure:
https://webkit-search.igalia.com/webkit/rev/c0c0524829fd2bebfa47a7ffad327558fd5f2672/Source/WebCore/css/mathml.css#46
https://webkit-search.igalia.com/webkit/rev/c0c0524829fd2bebfa47a7ffad327558fd5f2672/Source/WebCore/rendering/mathml/RenderMathMLToken.cpp#609
In any case for WebKit, the logical metrics and ink metrics match, so if it shows a small part of the background, that also means it adds slightly more gaps in math formulas, which we probably don't want. Gecko does not have this problem since it stores both metrics for each MathML box (which is what the core spec also does for now) and even has more complicated rules as discussed above.
davidcarlisle commentedon Mar 2, 2022
@fred-wang the second image is definitely much better and if that causes a few features about background colouring that need to be carefully explained I'd still say it looks like a win. The blink rendering is really starting to look nice. I'd support your initial implementation plan here.
clapierre commentedon Mar 2, 2022
Be careful, it is not recommended to have inline styling as it can not be overridden by a person who may be color blind or need to adjust these colors, font sizes etc.
could the same thing be done instead with CSS?
IE:
fred-wang commentedon Mar 2, 2022
@clapierre yes sure, putting CSS in a separate style sheet is valid in MathML. I only used inline style attribute to make the example less verbose.
dginev commentedon Jan 8, 2023
re Fred's comment #78 (comment)
I've stumbled on the flip side of that issue, where there is no gap at all, in the root case. Fred cross-referenced this issue in my Chromium report, so back-referencing that report here: https://bugs.chromium.org/p/chromium/issues/detail?id=1395834
I'll inline the image for convenience:

I'm nowhere near informed enough to make any useful technical comments on how MathML Core should be improved here.
Jamesernator commentedon Feb 26, 2023
I'm not sure if all of these problems are due to this cause, but it looks like the same issue. Basically pretty much all fonts (including the default) have weird behaviours with
<msqrt>in the Chromium implementation:Top and bottom of sqrts are not aligned:
Large gaps under sqrt are common:
The radical fails to line up with the overbar extender:
Both MathJax and Firefox (I have not checked Safari) have far more reasonable behaviour with their respective default fonts:
MathJax:
Firefox:
(Live demo of these issues, though you will need the fonts installed locally)
Bug 1908069 - Add border/padding/margin support to <mfrac>. r=emilio
Bug 1908069 - Add border/padding/margin support to <mfrac>. r=emilio
Bug 1908069 - Add border/padding/margin support to <mfrac>. r=emilio
Bug 1908069 - Add border/padding/margin support to <mfrac>. r=emilio
Bug 1908069 - Add border/padding/margin support to <mfrac>. r=emilio
Bug 1908069 - Add border/padding/margin support to <mfrac>. r=emilio
Bug 1908069 - Add border/padding/margin support to <mfrac>. r=emilio
Bug 1908069 - Add border/padding/margin support to <mfrac>. r=emilio
Bug 1908069 - Add border/padding/margin support to <mfrac>. r=emilio