Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[rtext] Font size is being treated as an integer, but stb truetype accepts float size #3766

Open
GaryMcWhorter opened this issue Jan 30, 2024 · 6 comments
Assignees
Labels
enhancement This is an improvement of some feature

Comments

@GaryMcWhorter
Copy link
Contributor

Issue description

Font size in raylib is passed along the api as an int, but truetype accepts a float value. The reason why this is important is because the sharpness of a font rasterized by stb truetype is highly dependent on this value, with steps as small as 0.05f making a noticeable difference. By using integer font sizes, only some fonts (especially affecting pixel fonts) are able to align properly to the rasterization grid. If we use a float value instead, we are able to fine tune the size necessary per font to reach perfect rasterization.

To enable this to work, a few functions and a struct need to be altered to change the type from int to float.
This is a big api change, but the results should be a great benefit.

Issue Screenshot

Here we can see a font rasterized at 13pt, with a severe subpixel halo:
image

Not good at 12pt either:
image

But 12.7pt works perfectly!
image

Code Changes

// raylib.h line 310
typedef struct Font {
    float baseSize;           // Base size (default chars height) <-- Change from int to float
    int glyphCount;         // Number of glyph characters
    int glyphPadding;       // Padding around the glyph characters
    Texture2D texture;      // Texture atlas containing the glyphs
    Rectangle *recs;        // Rectangles in texture for the glyphs
    GlyphInfo *glyphs;      // Glyphs info data
} Font;
// change fontSize from int to float for the following function signatures
// note, the respective forward declarations will need to be updated as well
// rtext.c line 361
Font LoadFontEx(const char *fileName, float fontSize, int *codepoints, int codepointCount)

// rtext.c line 507
Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, float fontSize, int *codepoints, int codepointCount)

// rtext.c line 565
GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, float fontSize, int *codepoints, int codepointCount, int type)
@raysan5
Copy link
Owner

raysan5 commented Feb 4, 2024

This is a breaking change and I'm considering it carefully. Also, it seems a bit weird that a font size should be requested with decimal values, it makes me think something is not properly considered on raylib internal font rasterizer...

raylib uses stb_truetype for font rasterization but maybe font size "points" and "pixels" are not properly calculated, it requires some further investigation before implementing this change.

@orcmid
Copy link
Contributor

orcmid commented Feb 4, 2024

@raysan5
It turns out that fractional font sizes (in points) are used real world typography and I suspect in quality renderings, such as with PostScript or other tools designed for high-quality rendering. Browsers seem to allow them but some (necessarily?) round to integral sizes (in the equivalent pixels) and in different ways.

PS: I just opened a blank document in Microsoft Word and see that the default Calibri font has a 10.5 pt setting. I know I have seen other fractional font sizes around the small end, usually with a .5 fraction. So there are at least TrueType fonts that can be rendered fractionally.

@designerfuzzi
Copy link

designerfuzzi commented Apr 4, 2024

@orcmid
pt != px != Units/Geviert (FUnits/EM)
Fonts are given in "Units/Geviert" since long before ttf existed. Pt is a unit that is based on unit/geviert and interpreted as fraction relative to dpi of the medium, in this case on screen (either 72dpi or 96dpi or even higher).
Microsoft Word shows particular pt in the fontsize selector because fonts on windows (and other) are either optimised to alignment to pixels or rendering uses aliasing that assumes line drawn based on vectors that will not disappear below the pixel threshold. Thats why fonts must be optimised to align on purpose in particular focusing some specific pt sizes, like 4.5, 5, 6, 7, 7.5, 8, 9, 11pt and so on. But the optimisation of fonts to align is not expressed in integer of pixels but integers of Geviert (em square) in other words fractions of em square.
All fonts can be drawn with fractions, but not all will result in good aliasing or good alignment.
here just an example of professional glyph development software.
Bildschirmfoto 2024-04-04 um 12 18 17
As you see there are no pt values at all in font development only definition what one em should be, resulting in fractions (float) relative to dpi and so also pt.
The screenshot shows values that match a perfect aligned font with 7px (at 96dpi) Versal-height.

That means it has literally nothing to do with postscript. Postscript is solely a format to pack data that also allows to give relative size of a sheet so it can be properly reproduced. In other words it supports printing systems, not screen systems.
Displaying fonts is always an alignment enterprise, unless we talk about bitmap fonts which are designed to only match certain bitmap sizes and some fixed scales.

@orcmid
Copy link
Contributor

orcmid commented Apr 4, 2024

@designerfuzzi

That means it has literally nothing to do with postscript. Postscript is solely a format to pack data that also allows to give relative size of a sheet so it can be properly reproduced. In other words it supports printing systems, not screen systems. Displaying fonts is always an alignment enterprise, unless we talk about bitmap fonts which are designed to only match certain bitmap sizes and some fixed scales.

I don't think that's completely accurate with regard to imaging with PostScript, Interpress, TeX, or other final-form imaging/printing systems. Those systems have to deal with font rendering via digital graphics, whether screens or laser printers. There are cross-overs between imaging on screens and on paper, although I do agree that the nomenclatures get murky.

My impression with raylib is that there is a confusion between pixels (and some presumed dpi) and other typographical measures with regard to text.

And thank you for the elaborate account.

@designerfuzzi
Copy link

designerfuzzi commented Apr 4, 2024

well if we'd take it not so narrow than pdf is successor to postscript.

"PostScript is a page description language developed by Adobe Systems in the 1980s. It describes the appearance of a printed page in a device-independent manner. PostScript files contain instructions that describe how to draw text, graphics, and images on a page, and they can be interpreted by a PostScript-compatible printer or by software that interprets PostScript code."
So for printers or 'rip (aka computers that render print data to generate physical templates for printing machines). Which typical lead to fonts being included in the postscript file, either as bezier paths or later as entire font's for which they needed to be standardised. So postscript is solely vector oriented and can keep images (usually as link) in place. Which also meant images where given on extra medium to the postscript file.

and the logic follow up on those widely accepted standards became PDF.
"PDF is a file format developed by Adobe Systems in the 1990s. Designed to present documents, including text formatting and images, in a manner independent of application software, hardware, and operating systems. PDF files can contain a variety of content, including text, graphics, multimedia elements, and interactive elements."
Which also solved the packing problem to keep images, fonts and so on in one package.
In fact postscript always needed an interpreter to be shown on screen for any double check before expensive printing. We still have those, formerly postscript viewers nowadays PDF viewers. Even if it might feel as if that is a native feature of modern OS'es it is still specific software sometime even with an entirely different rendering system.

The whole trick on modern font interpretation is about keeping font data as original as much as possible until the last step of rasterisation is inevitable. Which is the case with opengl/raylib of course.

@orcmid
Copy link
Contributor

orcmid commented Apr 4, 2024

@designerfuzzi I don't want to continue this conversation since it is now far afield from the subject of this discussion. I do want to correct some historical difficulties with the material you are quoting. I do agree with the statement

The whole trick on modern font interpretation is about keeping font data as original as much as possible until the last step of rasterisation is inevitable. Which is the case with opengl/raylib of course.

I would like to point out that PDF started out as a customization of PostScript to be page-oriented, which PostScript did not require. Also, PostScript was used in a sort-of-native way on the original Macintosh. It is not appropriate to think of one as a subset or successor of the other. The prominence of PDF as a mostly-final-form document-interchange format is well-earned of course.

I also worked on a project where Adobe provided a preprocessor board for Windows PCs that would emit Interpress from Postscript files. This was to allow a document processing flow from Windows through a Windows-based server that acted as a front-end to DocuTech, which used XNS protocols and ripped Interpress. That work was done prior to announcement of DocuTech. I don't know if it ever shipped.

I worked on a similar project that used a form of ODA and shipped images through a customized Unix server to DocuTechs. This was used in a book preservation project at Cornell University, and the resulting scanned documents are available online from there. They could also be printed and bound on-demand via a DocuTech installed there. There are no font issues here, and the differences between write-white and write-black xerographic printing not a particular issue at 1200 spi :).

More than that, I recall when all of those document-publishing forms were introduced and I knew some of the people involved. That's an interesting use of "rip." I'd forgotten about that. I use PDF/A wherever I can :).

My contemporary Donald Knuth's experience with the creation of TeX and the creation and handling of fonts provides a great public account as he strove to provide publication quality laser-printed photo-lithography masters that would be used to provide beautiful mathematical texts and notations in his series of books and those of others. There is great attention on font scalability including adjustments to how our eyes deal differently with fonts on different sizes, requiring anamorphic thickening toward the small end.

@raysan5 raysan5 self-assigned this Apr 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement This is an improvement of some feature
Projects
None yet
Development

No branches or pull requests

4 participants