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

Text: allow font to specify unicode character ranges #13

Open
lojjic opened this issue Aug 26, 2019 · 9 comments
Open

Text: allow font to specify unicode character ranges #13

lojjic opened this issue Aug 26, 2019 · 9 comments

Comments

@lojjic
Copy link
Collaborator

lojjic commented Aug 26, 2019

See corresponding CSS feature: https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/unicode-range

The font property should accept an array of unicode-range-to-font-file mappings.

lojjic added a commit that referenced this issue Mar 1, 2022
…t by unicode range - #13

Mimics how CSS @font-face resolves across multiple fonts by unicode-range, only loading
those font files needed for the characters actually used. This allows for more complete
language coverage without having to include everything in one font file, and Latin text
can now load a smaller font file by default. The support is currently limited to an
internal set of fallback fonts, but it will be opened up to the public API soon.

Internally this required supporting varying font metrics between characters, which also
sets us up for inline styling e.g. varying font-size, font-style, etc. - see #65
lojjic added a commit that referenced this issue Mar 16, 2022
…t by unicode range - #13

Mimics how CSS @font-face resolves across multiple fonts by unicode-range, only loading
those font files needed for the characters actually used. This allows for more complete
language coverage without having to include everything in one font file, and Latin text
can now load a smaller font file by default. The support is currently limited to an
internal set of fallback fonts, but it will be opened up to the public API soon.

Internally this required supporting varying font metrics between characters, which also
sets us up for inline styling e.g. varying font-size, font-style, etc. - see #65
@lojjic
Copy link
Collaborator Author

lojjic commented May 11, 2022

Also see #206 - this unicode-ranges work enables the specification of default fallback fonts for greater out-of-the-box unicode coverage.

@morandd
Copy link

morandd commented Sep 23, 2022

+1 request for this feature. Out-of-the-box unicode support is fairly fundamental for the modern web.

Just an idea, is it possible to leverage the system fonts? The Noto font .woff / .ttf files for Japanese alone are 6mb! Leveraging system fonts would afford a big download savings. So the idea would be to render the unicode string to an offscreen canvas using the browser text rendering engine, then use getImageData() to read that canvas and create the SDF which gives the beautiful WebGL fonts.

This Mapbox repo seems to do something like that:
https://github.com/mapbox/tiny-sdf

Since global unicode is a hard requirement for my project I'll try now switching to mapbox/tiny-sdf -> canvas -> THREE.CanvasTexture() to generate text, and keep a Watch on troika-text to see if unicode makes an appearance. Troika generates beautiful text easily; just wish it had complete glyph coverage.

@lojjic
Copy link
Collaborator Author

lojjic commented Sep 23, 2022

is it possible to leverage the system fonts?

No, unfortunately, there is no browser API yet for accessing system font data. The only way to use system fonts is as you suggested, which works for certain use cases. If that works for you then definitely go for it!

@morandd
Copy link

morandd commented Sep 24, 2022

I guess my point was, there are a couple of libraries that will generate SDFs using system fonts:

https://github.com/mapbox/tiny-sdf
https://npm.io/package/pixi-richtext
https://github.com/mapbox/fontnik

By coupling those SDF generators to the text layout engine, shader, and THREE bindings in this package it should be possible to generate complete sharp, complete, unicode text on the fly without any downloads.

I really appreciate your excellent work on troika. I just post this comment because it seems we are this close to being able to have on-the-fly, 3d, complete unicode text. I wish I had the fluency with GLSL to bind to tiny-sdf and submit a PR instead of merely a comment.

@lojjic
Copy link
Collaborator Author

lojjic commented Sep 24, 2022

Ah, if only it were that simple! 😉

The font files are needed for more than just SDFs. They also contain data for glyph metrics, layout, ligatures and joined characters, et cetera. The libraries you mentioned are great for simple glyphs, or for full strings, which is why I said they work for certain use cases - like if you have a relatively small number of short single-line labels. Unfortunately that isn't sufficient for all troika-three-text aims to support.

@lojjic
Copy link
Collaborator Author

lojjic commented Sep 24, 2022

I guess I should mention, I do plan at some point to offer an optional fallback mode to utilize canvas rendering to assist with certain characters not covered by an actual font file - mostly for emojis but it could also be a not-perfect-but-fairly-ok option for CJK character sets specifically, which tend to not have complex layout or joining rules and are among the largest font files.

@morandd
Copy link

morandd commented Sep 25, 2022

OK, thanks for clarifying.
Also, I look forward to when the unicocde-ranges support is released.

short single-line labels.. [snip] ... for CJK character sets

This would be amazing, and I guess would cover 50-80%+ of the common needs.

Your Troika text just looks so much better than canvas text. I wish we could have this for CJK labels.

@morandd
Copy link

morandd commented Sep 25, 2022

To add a comment that might help others who stumble into this thread:

I spent a few hours unsuccessfully trying to create a custom font that contains the unicode glyphs to display. Where the file "input.txt" contains all the characters that might need to be rendered, and given GoNotoCurrent.ttf, running the command

pyftsubset GoNotoCurrent.ttf  --layout-features='*' --text-file=./input.txt --output-file=test.ttf 

That generates a manageable 1.2mb font, but I get a bunch of "unsupported GPOS table "errors like "unsupported GPOS table LookupType 6 format 1" from Typr in the browser and still the Tofu no-glyph boxes from Troika-text.

Suggestions welcome. Perhaps some better settings for pyftsubset can fix this. If we can diagnose this problem it could be a workaround for those who want to support more global langauges.

lojjic added a commit that referenced this issue Dec 15, 2022
…t by unicode range - #13

Mimics how CSS @font-face resolves across multiple fonts by unicode-range, only loading
those font files needed for the characters actually used. This allows for more complete
language coverage without having to include everything in one font file, and Latin text
can now load a smaller font file by default. The support is currently limited to an
internal set of fallback fonts, but it will be opened up to the public API soon.

Internally this required supporting varying font metrics between characters, which also
sets us up for inline styling e.g. varying font-size, font-style, etc. - see #65
lojjic added a commit that referenced this issue Jun 29, 2023
…t by unicode range - #13

Mimics how CSS @font-face resolves across multiple fonts by unicode-range, only loading
those font files needed for the characters actually used. This allows for more complete
language coverage without having to include everything in one font file, and Latin text
can now load a smaller font file by default. The support is currently limited to an
internal set of fallback fonts, but it will be opened up to the public API soon.

Internally this required supporting varying font metrics between characters, which also
sets us up for inline styling e.g. varying font-size, font-style, etc. - see #65
lojjic added a commit that referenced this issue Sep 8, 2023
…upport (#279)

* feat(troika-three-text): initial support for multiple font files split by unicode range - #13

Mimics how CSS @font-face resolves across multiple fonts by unicode-range, only loading
those font files needed for the characters actually used. This allows for more complete
language coverage without having to include everything in one font file, and Latin text
can now load a smaller font file by default. The support is currently limited to an
internal set of fallback fonts, but it will be opened up to the public API soon.

Internally this required supporting varying font metrics between characters, which also
sets us up for inline styling e.g. varying font-size, font-style, etc. - see #65

* feat(troika-three-text): add fallback fonts for CJK and support 'lang' prop

* feat(troika-three-text): add Noto Emoji font to fallback list

* fix(troika-three-text): add CJK punctuation to unicode ranges

* feat(troika-three-text): add Arabic and Chinese texts to example

* feat(troika-three-text): integrate unicode-font-resolver for full unicode fallback font coverage

* chore: allow unicode-ranges branch to publish prerelease versions

* v0.48.0-unicode.0

* fix: fontResolverWorkerModule wasn't exported

* v0.48.0-unicode.1

* fix: fix hang on zero-length text

* v0.48.0-unicode.2

* feat: add fontWeight and fontStyle params for fallback font resolution

* v0.48.0-unicode.3

* fix: pre-transpile the unicode-font-resolver lib

* feat: allow configuring unicode-font-resolver data URL

* docs for unicode font loading

* v0.48.0-unicode.4

* chore: update unicode-font-resolver to 1.0.0
@eXponenta
Copy link

is it possible to leverage the system fonts?

No, unfortunately, there is no browser API yet for accessing system font data. The only way to use system fonts is as you suggested, which works for certain use cases. If that works for you then definitely go for it!

https://developer.mozilla.org/en-US/docs/Web/API/Window/queryLocalFonts

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants