-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
p5 loadFont() and its dilemma with opentype.js #6391
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
Comments
Welcome! 👋 Thanks for opening your first issue here! And to ensure the community is able to respond to your issue, please make sure to fill out the inputs in the issue forms. Thank you! |
Thanks @munusshih. I'm inviting some typography contributors to this discussion @dhowe @kyeah @aahdee @limzykenneth @davepagurek |
What do X and O represent in the table? If O is a supported feature, should the top right cell of the table be an O? This is a tough one. If we rely only on js canvas, then we get all the features it has, but it also prevents us from extending those features at all, since it doesn't give us access to the underlying data. I don't think there's a way we can support That said, we don't want to reinvent the wheel, especially for something as complex as font layout (the fact that it's so hard to find a JS library that does everything we need is maybe a testament to how hard it is!) Maybe another option is to try to rely on a more battle-tested library from outside of the Javascript ecosystem, and compile it to JS via emscripten? Something like Pango? Building a C library for JS is a big task in itself, but that might still be easier than patching variable font support AND layout support into opentype.js and p5. |
@davepagurek Edited! Thanks for pointing that out. Got a little confused in making the table in markdown. I was originally thinking of having the two system co-existing like what we have right now, but prioritize CSS@font-face as the main rendering way for 2D texts to better support the HTML Canvas API, and have opentype.js stand as an support system for WEBGL and p5.font solutions. This however, might be a BIG change in code as it is the opposite logic now (prioritize opentype.js and have CSS@font-face as a supportive system). |
Not a trivial problem (the two font-handling pathways have always bothered me). If we had a way to handle text in opengl, I might arguing for moving p5.font to an external library, for the sake of simplicity. In any case perhaps it would be helpful to spec out the 'must-have' and 'would-be-nice' functionality... |
To clarify, would that be for "extra" things like
Yeah, I feel like having two code paths for such a complex system might open us up to more bugs once we start adding more things like variables and layout into the mix. If it's possible to use a library that does everything we need, it would be nice to load a default font if unspecified and use the same system everywhere. But that's also a big "if" :') |
I'm not a seasoned contributor, so I might miss some points, but I'm happy to share my thoughts. Some comments on your table @munusshih: Loading font using loadFont() prevents the use of the variable-axis and native API Access a Google Font with opentype.js Some direction might be found in this proposition for glyph support (though it might be outdated): And I didn't have the time to explore fully, but it seems there might be clues on how to load system fonts as font data here: About opentype.js |
And what about geometries ? Since we get all we need to make it a mesh, how expensive would it be to have characters being |
TIL about the SFNT data access in the local fonts API! That's pretty cool, and could let us do what opentype.js lets us do but for local fonts. I hope they add to the spec to give that same access for web fonts.
We actually do something like this at Butter now! The main issue we had to work around is that the level of vertex detail you want depends on both the size of the text, and how far from the camera it is, so a single p5.Geometry glyph may not look good if you move closer to it. We ended up with a caching system, but we also don't give users full camera control, which bounds the complexity a bit. For something like p5 we'd maybe need to make a version of p5.Geometry which knows how to dynamically regenerate itself for different scales, which could be a feasible solution instead of shaders. It'd probably still need to know about the bezier paths for all the glyphs though, so we'd still need opentype.js for web font support. Also, one other idea: In the initial implementation PR for the WebGL font shader, there was some discussion of SDF fonts. They're less accurate than just using the fonts' bezier paths, but could plausibly be generated from 2D canvas renderings of glyphs without ever looking at the font data. |
Yeah, that's also a possible solution. I've been documenting this for a later attempt but never really delved into it. |
Just to enumerate the ideas we've discussed so far, here's a new pros/cons list. If we make SDFs of text:
If we find a replacement library (e.g. Pango, which supports layout and glyph info):
If we support two systems:
|
do we currently do this with another library ? |
@dhowe not yet! there are other libraries on GitHub we could look at for guidance, but it'd be something new for us. |
right, wasn't sure if I had missed this... anyhow, I'd caution against such a path (Pango or a similar port), unless there really are no other options -- the added complexity can be significant |
Topic
As @amehowc mentioned in his p5.varaibleFont library
There are two primary methods for loading and using fonts in p5.js. One involves using loadFont(), and the other is by defining a font either through CSS with a @font-face tag or importing it via an API like the Google Fonts API. Both methods have the same end result when using text() in the 2D context. However, differences emerge when you delve into font data functions like font.textToPoints() or font.getBounds(), or when using the WEBGL context.
Basically it could be drawn into a table like this:
O = supported feature, X = unsupported feature
The two ways of loading fonts create different supports in p5 for these typographic related functions.
Supports for native Canvas API
The loadingFont function
Basically if you import font using the
loadFont()
function, it will still create a CSS @font-face for you in the code as shown here in loading_displaying.js:p5.js/src/typography/loading_displaying.js
Lines 125 to 133 in 36437b3
However, it will not be referencing it, so I'm really unsure if this part of the code is even working.
The text was updated successfully, but these errors were encountered: