-
Notifications
You must be signed in to change notification settings - Fork 477
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
Support for GPOS table parsing #19
Comments
You're absolutely right, we need to support GPOS. Thanks for the tip on suggesting the Google repo; that's a great set of test cases that I can use for regression tests. |
I've been searching left and right, and it doesn't seem like there's any other working implementation in JavaScript for GPOS table. Having this in opentype.js will be extremely valuable for the JS community. The most popular and mature library seems to be TTX/FontTools written in Python. Extracting GPOS table is a matter of executing: ttx -t GPOS /path/to/font.ttf And then convert the XML output to JS objects. Still, it sucks not being to do this in a pure JS stack at the moment. Perhaps TTX/FontTools could serve as a good implementation reference? |
I highly recommend against reinvent a shaping engine in JavaScript. If you have to, check https://github.com/prezi/harfbuzz-js For a JS-only solution to loading GPOS, check https://github.com/Pomax/A-binary-parser-generator by @Pomax |
I expect opentype.js just needs fontTools style access to the data, not But yes, pomax's solution is better than coding it directly :) |
Thanks @behdad for pointing out @Pomax repo. Unfortunately his current OpenType.spec file doesn't have any definition for GPOS table (it's empty): https://github.com/Pomax/A-binary-parser-generator/blob/master/OpenType.spec I know I can try to dig up the spec and put in the missing piece, it's just a real PITA not having anything that works out of the box in JS. |
Just want to add that the ability to measure text geometry (precisely with kerning) in pure JS is priceless for future web apps. (especially ones using Canvas / WebGL rendering) Currently one can simply use native canvas measureText() for width. However the process has to be done in the main UI thread (no Canvas context access in Workers), and it's very slow for large amount of text. Imagine being able to perform application layout in multi-threaded manner, with multiple independent chunks of texts being measured in parallel from multiple Workers. opentype.js (and some other libraries) opens up the possibility to achieve that. The only missing piece I found was kerning data in GPOS table. |
Behdad, want to do it? :) |
I'm currently busy with writing a glyphlet font generator (in a way that would be extensible to larger fonts in the future" but I might be able to revisit the parser generator after I'm done with that. Getting in the spec model for the common table format script/feature/lookup will be a bit of a challenge =) |
What is a glyphlet font?
|
a font containing a single target glyph (not counting empty glyphs used to effect things like ligature substitution). In this case it's for dynamic fonts with a single outline define in SVG or Type2, and then the js builds it on page load for use as a tiny, tiny otf/woff |
Unfortunately you are wrong. The only missing piece is the equivalent of all of HarfBuzz. Unless you only care about simple scripts and no ligatures that is. This means, no Arabic, no Indic, etc. |
Like adobe blank but better in some way?
|
adobe blank is an empty font for testing other-font-support with full unicode support, Think of glyphlet fonts more as subset fonts where the subset is a single character. It's a bypass to get a decorative graphic piece of "text" injected onto a page without needing to download a full font, and without needing to download a potentially large number of small files. (you give up some power in terms of kern/GPOS, but typically you're not using them inside running text so kerning is rarely an issue) |
So a 'glyphlet font generator' is a 'extreme subsetter'? :) |
haha, without a basefont to subset from, yes =P (especially with minimal:true and compliant:false, which rips out everything browsers don't look at, plus a few things browsers look at until OTS gets updated so they don't =) |
On 25 February 2014 18:16, Mike Kamermans [email protected] wrote:
So this is something like simpleSvgDrawing2CffFont.js ? |
I'm not tying it down to an "anything" that isn't a glyphlet font generator =)The easiest POC while I work on it for testing etc. is using an svg path for the glyph outlines. |
on a more thread-relevant note: for completion you probably want GSUB as well as GPOS, rather than merely GPOS. It uses the same OpenType "common table layout" for encoding the script/feature/lookup "tree" (just like GDEF, BASE and JSTF), so most of the work for GPOS automatically gives you most of the code for GSUB, too. Not sure if I'd go with the xml from TTX and then making objects out of that, given the highly connected graph that is the common table layout structs: you probably want to read the opentype spec on how those work and instead look at the .py code for the common table layouts. It's not one-on-one containment, making it quite messy if you're basing it on what TTX generates, rather than the structs it uses to generate. |
So I finished part of the work I wanted to do with glyphlet fonts, yield code that is pretty compatible with opentype.js (although I rewrote my single file POC to a require.js module based codebase, which I can strongly recommend for opentype.js, too =). It has GSUB at the moment, but no GPOS (yet? although GPOS for a single glyph doesn't make the most sense of course); https://github.com/Pomax/CFF-glyphlet-fonts/blob/gh-pages/src/SFNT/tables/GSUB.js plus the structs from https://github.com/Pomax/CFF-glyphlet-fonts/tree/gh-pages/src/SFNT/tables/common and https://github.com/Pomax/CFF-glyphlet-fonts/tree/gh-pages/src/SFNT/tables/common/GSUB work together to generate GSUB tables, but there is a provision for a parse comment, which is more opentype.js's territory (although that said, I might simply write the parsing as generically as I can and see what that means for understanding what kind of syntax I need to make GSUB work as part of the .spec file for the binary parser generator project. Offsets to structs relative to "the most recent local field" are ... tricky) |
Isn't https://github.com/prezi/harfbuzz-js useful for this as Behdad said? Reading the tables is straightforward but interpreting them to know which glyphs to show is a huge task - done by harfbuzz |
Thanks @Pomax! The declarative tables parsing was something that I used initially in opentype.js. I'll look into your work soon. I have absolutely no feel for how many work it is to support GPOS and GSUB. Does it make sense to have simple, built-in support for Western fonts (basically the same data as I would get from the KERN table), and then use harfbuzz-js as an optional dependency for more complex scripts? |
I'd say no to treating western as somehow special just because that's what you're used to in your browsing experience (it's certainly mine, but I try to stay far away from treating latin as somehow special). Also, to using harfbuzz: yes and no. Harfbuzz.js definitely sounds like the way to go for "proper full blown parsing", but I had a look at trying to use it, and it has essentially no documentation, so if we want harfbuzz uptake it's going to need some docs that don't require people to build harfbuzz.js and the docs from source. It needs to be an actual JS library with an API instead of something that can be compiled out of regular harfbuzz. |
Besides Latin, Greek and Cyrillic scripts are more complex than you think. Some languages or uses need relatively complex GPOS and GSUB. |
Being able to extract from the GPOS table the same data there is in the kern table would certainly be a good start. Full support could be a second step, maybe with the help of an external dependency. |
that's not really how GPOS works though. GPOS is basically a generic set of datastructures, where the only reason it's latin is because the script tag happens to be "latn", so either you pretty much already have your full GPOS, or you don't. The kern table is a lot simpler, but also increasingly less available as more fonts switch to GPOS |
I was just talking about getting the Pair Adjustment Positioning Subtables, format 1 and 2. I'm not talking about restricting to latin, which makes little sense, but restricting to the basic GPOS kerning feature. Other GPOS features and subtables could come later. |
Just submitted a PR : #20 |
@davelab6 Although full GPOS support is not yet complete, I think it's good enough for now. Let's close this and we can continue on a different issue # later on with more specific use cases. Great work guys! |
Most fonts from Google repo (http://www.google.com/fonts) use the GPOS table for kerning data, and many don't include the old "kern" section, which currently causes missing kerning data from opentype.js.
IMO this is an important feature to support. Safari and Firefox both turn on kerning by default for all text. Not being able to take kerning into account leads to:
The text was updated successfully, but these errors were encountered: