Extensible integral issues
Opened this issue · 9 comments
Problems
I see two problems with the extensible integral.
- When composing extensible integrals, fonts use the official unicode slots:
uni2320 TOP HALF INTEGRAL
uni23AE INTEGRAL EXTENSION
uni2321 BOTTOM HALF INTEGRAL
The extensible recipe for uni222B uses uni2320 and uni2321 for the top and bottom pieces, but an unnamed glyph "integral.x" for the repeating piece. Why not uni23AE for the extensible piece?
- The "integral.x" piece (this also applies to uni2320 and uni23AE) seems to be shifted horizontally:
In the picture we see that it has a VStem hint starting at x-coordinate 281. When using the glyph, it magically gets snapped to the hint (from its placement at 562 in x-direction). I wonder if that is on purpose.
Suggestions
- Change the extensible recipe for uni222B so that the middle piece points to uni23AE instead of to "integral.x".
- Move the glyph in "integral.x" into uni23AE (the width of the current uni23AE is wrong, see picture below, the red one, where that piece is stacked with the top and bottom pieces)
- Fix the glyphs in uni2320 and the new uni23AE so that they are correctly placed, and so that no snapping to the VStem is needed. (I wonder if this applies to more glyphs?)
In the image above, the left integral is the one built from uni2320, "integral.x" and uni2321. Note that the pieces match well. To the right, it is uni2320, uni23AE and uni2321 stacked on top of each other. Note that the current uni23AE is too thin.
The Unicode composing integral element characters are legacy mechanisms, outside the framework for dynamic extension used with the OpenType MATH table and associated math layout handlers. This is not to say we shouldn’t try to make them work as well as possible, but that they were not prioritised. I can review their size and alignment.
The extensible construction is in fact working (the black integral to the left in the picture is OK), since the recipe for the integral points to the glyph that is correct. I do not understand, though, why the private "integral.x" is used instead of the official slot for the middle piece.
Regarding point 3 in the list of my suggestions, maybe I was too quick. It seems that the whole Stix two math font is built with this hint/glyph shifting(snapping?) in action (if not, I misunderstand FontForge). Here is lower case italic a:
I've been staring at many other OpenType math fonts, but I have never seen this method to place the glyphs used before. If I generate from FontForge a version without hints, all glyphs indeed sit wrong.
I wonder why the font is built as it is, with the hints and glyphs shifted, but since the output is OK, I guess that is not a real issue.
I can’t speak to what you see when you crack compiled fonts open in FontForge. That’s not part of the build tool chain, and we hint using autohint tools during the scripted build, not in our upstream design sources.
I do not understand, though, why the private "integral.x" is used instead of the official slot for the middle piece.
There is no ‘official’ element for the middle of the integral in the context of MATH table layout. The /integral.x/ glyph is used across a lot of different assemblies, not just the integral sign; whereas U+23AE is a legacy encoding particular to the integral and limited in its applicability because it must be presumed to be a full em height element, while the effective height and overlap of the generic extender /integral.x/ is managed in the MATH table.
I can’t speak to what you see when you crack compiled fonts open in FontForge. That’s not part of the build tool chain, and we hint using autohint tools during the scripted build, not in our upstream design sources.
I don't know what "crack compiled fonts open in FontForge" means, but I understand this as FontForge was not used to create the Stix two math font, and that FontForge in this case for some reason introduces a shift of the glyphs when opening the hinted font. If so, the third point in my suggestion list can be forgotten.
There is no ‘official’ element for the middle of the integral in the context of MATH table layout.
Can you point to the reference of the math table layout? I am not aware of it, and as far as I have understood, it is more or less Cambria that has set the standard.
The /integral.x/ glyph is used across a lot of different assemblies, not just the integral sign;
When I unpack the font and look for uses of "integral.x", I only find that it is used in the integral and the ss08 (upright) integral, but maybe I miss something.
whereas U+23AE is a legacy encoding particular to the integral and limited in its applicability because it must be presumed to be a full em height element, while the effective height and overlap of the generic extender /integral.x/ is managed in the MATH table.
I do not understand these legacy statements. When I go to unicode.org and search for the Ux23AE, it shows this, with name "INTEGRAL EXTENSION". If that is not an official integral element, I don't know what it is. All other math fonts I have looked at, that have a recipe for the integral, including Cambria, use this glyph. Maybe it was used differently in the past, but all modern fonts seem to agree on how it should be used now.
I also do not understand the text about the em height (never heard of em heights). I see it like this: The middle piece needs to be a rectangle, it needs to have a matching width that fits with the top and bottom pieces (including the right horizontal location), but it can have any height as long as the recipe is setup right. (The resulting integral might look bad, though.)
The MATH table spec is here
https://learn.microsoft.com/en-us/typography/opentype/spec/math
The point is that the MATH table assemblies work entirely in glyph space, so are not directly related to any Unicode characters such as U+23AE. The assemblies are mappings from the default glyph for the integral sign to dynamic composition of larger versions of that sign from multiple glyphs, whose overlaps are defined in the MATH table. The glyphs that make up the assembly are arbitrary, and at the decision of the font maker. In the case of the STIX Two Math font, we’re working with some inherited data in the MATH table, some of which we’ve changed, and some of which we have not. I will definitely be looking at the distinction between /integer.x/—which I thought was more widely used—and /uni23AE/, and figuring out whether there are any dependencies that would be affected by keeping the data as it is vs changing it as you suggest.
By ‘legacy’ I mean that Unicode encoded some things that were used in older layout mechanisms to cobble together multi-line integral signs, but that is not how OpenType math layout works. The legacy assumption is that U+23AE is the full height of the body size of the font (the em), like e.g. a boxdraw character in a terminal emulator, because that is how the older multi-line layout used to work in metal type etc.. What you say about it having ‘any height as long as the recipe is setup right’ presumes the glyph for this character is being used in the MATH assembly, which is can be but does not need to be, and if so used would be entirely independent of its encoding in Unicode: it would just be the arbitrary glyph defined for the purpose in the MATH table, like /integer.x/ currently is.
Regarding the shifting in FontForge:
After looking at the (rather interesting) build process of STIXTwoMath-Regular, it looks like the problem is that FontForge reads and obeys Bit 1 in the flags section of the head. This is set to 0 in the font. I don't know why this happens only for the STIXTwoMath-Regular font, and not for other fonts, perhaps because of how it is built (starting with the input.ttf).
In any case, I have opened an issue over at the FontForge repository.
Thanks for the investigation. I’ll look into this and query with our tool developer if any flag settings look incorrect.
Note that the .input.ttf file is only used as a source for discreet tables (OpenType Layout tables and the MATH table) that are imported into the final font during the build process. The head table and everything else is written using various open source tools during the build process, and is not copied from the .input.ttf file.