adobe-fonts / source-sans

Sans serif font family for user interface environments
https://adobe-fonts.github.io/source-sans
SIL Open Font License 1.1
3.49k stars 229 forks source link

With heavy freetype hinting, in "spade" not enough space between 's' and 'p' #193

Closed Mikolaj closed 4 years ago

Mikolaj commented 4 years ago

First, thank you very much for the fonts. They are incredibly useful.

Second, on this screenshot in line 11, the red "spade" has not enough space between 's' and 'p' and perhaps a bit too much between 'p' and 'a'.

image

This was rendered with the TTF_RenderUTF8_Shaded operation of SDL2-ttf (which uses the freetype library under the hood) at size 16px, based on the semibold .ttf font file I compiled from yesterday's version of your repo (using equally fresh afdko binary download) with build.sh, where the only modification I've done was replacing 'g' with the single-story version.

Interestingly the whole text looks completely different when the only change is using the .woff version of the file downloaded from http://google-webfonts-helper.herokuapp.com/fonts/source-sans-pro?subsets=latin,latin-ext, called source-sans-pro-v13-latin-ext_latin-600.woff:

image

Here the spacing between 's' and 'p' is wider and between 'p' and 'a' narrower, which looks more consistent. [Edit: judging from "Last modified 2019-07-23 (v13)" they just use an older release of the font.]

However I strongly prefer the generally much larger spacing in the new version (because the font is very thick (and regular is too thin for dark colours on black background) and with bright colours on black background it's quite glaring, so bigger letter spacing helps a lot). Also, I love the fact that the right vertical line of 'H' is not narrower than the left one in the new version of the font (the inconsistency also happens in a few other glyphs in the version from http://google-webfonts-helper.herokuapp.com and also 't' and 'f' are single pixel thin, which is not necessarily bad, but different from the new version).

BTW, I've just checked and the silly look of the double-story 'g' is only a feature of the http://google-webfonts-helper.herokuapp.com version, it's not present in a pristine original compilation of the new version of your fonts I've just built for comparison:

image

frankrolf commented 4 years ago

This very likely is a result of the rasterizer used. My suspicion is that this particular example of spade makes p and a coincide in a way that a new pixel is started for a – perhaps SDL2-ttf does not support sub-pixel letter spacing?

What happens if you slightly change the font size, or change the set width so spade moves to a different place?

Mikolaj commented 4 years ago

SDL2-ttf does antialising, but I don't know the exact method they use. If you look closely, the spacing between the two pairs of letters is always the same whenever they repeat in the text, so I'd rather suspect another feature of the rendering algorithm or the font definition or translation to TTF.

I've tried the same, but rendered at 17px, not 16px and the spacing between 's' and 'p' is fine, while between 'p' and 'a' is still rather wide, but doesn't cause any discomfort in absence of reduced spacing it would contrast with.

image

Anyway, if the rendering software is suspect, I can try to reproduce this with different systems, e.g., browsers.

Mikolaj commented 4 years ago

Another data point: it doesn't happen with the Regular weight of the font (and the previous too little space after 's' and too much space before 'a' in semibold is not affected by the random translation from weight change earlier in the line):

image

Mikolaj commented 4 years ago

Update: I'm sorry to report that when I use OTF version of the font I compiled, the result is as condensed as the older version I got from http://google-webfonts-helper.herokuapp.com. OTOH, the "spade" issue is not present. Perhaps the otf2ttf or ttfcomponentizer tool is currently broken? Before I report there, I'd be grateful for you troubleshooting help.

That's a sad news to me, because I hoped the increased space between letters in semibold variant is a feature, not a bug.

Edit. I've tested with file TTF/SourceSansPro-Semibold.ttf and WOFF/TTF/SourceSansPro-Semibold.ttf.woff and the effect is the same as with the fonts compiled by me ("spade" wrongly spaced, more space between letters), so if there is a bug in OTF to TTF conversion, it must be there at least since Sep 5, 2019. I've also checked the TTF format of the older version of the font served from http://google-webfonts-helper.herokuapp.com and it doesn't have the "spade" problem, so it's either triggered by last changes to the font or a bug in OTF to TTF conversion that wasn't there on 2019-07-23.

It may very well be a bug in TTF rendering in the freetype rendering library on my system that is triggered by something that happened in the font files after 2019-07-23. I should try on another OS to verify that, unless you have any better troubleshooting tip.

frankrolf commented 4 years ago

Would you consider testing the pre-compiled font files available under /releases?

Mikolaj commented 4 years ago

Yes, I failed to mention the "TTF/SourceSansPro-Semibold.ttf and WOFF/TTF/SourceSansPro-Semibold.ttf.woff" files above are downloaded from the release branch of github. When I compile I don't get any .woff fonts (BTW, I'd love get hold of the script that creates them).

Mikolaj commented 4 years ago

I've just tested this, with the same game, on Windows Vista, with version 2.10.1 of library libfreetype6 and it works absolutely the same as on my normal computer, which us Ubuntu 16.04 with verion 2.6.1 of library libfreetype6.

The newest version of this library is 2.10.2, according to https://www.freetype.org/, released in May 2020.

IMHO, this is a strong clue that the ttf (and ttf.woff) version of the font, since late 2019 at least, renders not as intended on many or all devices with many or all versions of libfreetype, the most widely installed font rendering library in the world.

Mikolaj commented 4 years ago

I've got a lot of new data from experimenting with TTF_SetFontHinting (https://www.libsdl.org/projects/SDL_ttf/docs/SDL_ttf_26.html#SEC26, http://freetype.sourceforge.net/freetype2/docs/reference/ft2-base_interface.html#FT_LOAD_TARGET_XXX), so let me just dump it without any hypotheses first.

OTF file, no TTF_SetFontHinting setting:

image

TTF file, TTF_HINTING_LIGHT set (which is almost identical, but with slightly thinner lines than the same setting with OTF file):

image

TTF file, TTF_HINTING_NORMAL set, which is the default if nothing set:

image

TTF file, TTF_HINTING_NONE set (which is very similar, but with thinner lines than the same with OTF file):

image

Mikolaj commented 4 years ago

My hypothesis of what is going on: OTF default, OTF light and TTF light use the light hinting that only changes vertical position of letter lines. All three do this slightly differently, TTF light having the thinnest lines. There are no letter spacing defects and it's very tight.

TTF default uses heavy hinting, which probably changes horizontal position of lines and does a worse job of changing the vertical position, hence the too thin dot in 'i'. It apparently doesn't try to preserve the average width of letters, but errs on the side of extending them, in consequence making words wider. Letter spacing doesn't seem to be consistently enlarged, but is rather random due to hinting, and given very tight spacing of the original font (if the light hinting really represents its original horizontal rythm) the randomness results in on average larger letter spacing.

The exception is 's', in particular before 'p', which always has the original (or even slightly lower?) tiny spacing on the right.

The "none" hinting version is a mystery to me. I seem to have very similar letter shapes to light, but lowered by one pixel and with extra letter spacing consistently added throughout. Again 's' sticks out, being the only, I think, case where the extra letter spacing is not added.

I can't tell if "sub-pixel spacing" is enabled or disabled in any of these nor how it matters nor how it matters to the exceptional behaviour of 's'. I'd rather expect either the glyph definition or kerning definition for 's' to be special.

A humble question: could 's' be tweaked to accommodate the font users that prefer the heavy hinting (which is the default for .ttf and .ttf.woff versions of the font) or the 'none' hinting modes of the libfreetype6 library (which is installed on the highest absolute number of machines of all font rasterizers in the world, if that helps)? That would benefit both the font users that prefer a heavier hinting and those that prefer higher letter spacing, but their rasterizer does not permit letter spacing modification (which is, sadly, the case for libfreetype6).

Mikolaj commented 4 years ago

[Disclaimer: I don't know what I'm doing.] I've tried completely gutting out kerning and hinting for the 's' glyph and no effect. The only tweak that works is increasing advance width by 20.

frankrolf commented 4 years ago

Thanks for all your research, this is very interesting! The letter spacing within the fonts is deduced independent of any rasterizer, this means that printouts are made, screen display in different applications in taken into account, etcetera.

It is hard to optimize fonts for any rasterizer, because one can never predict the users' settings and setup – even the most common rasterizer in the world is just one out of many.

Since @pauldhunt is currently working on a new release of the fonts, he can have another look at the sp combination, however I think he has done his best to ensure proper spacing in most situations.