opentype.js
opentype.js copied to clipboard
Fix test cases for CMAP, GPOS and GSUB
Thanks to @fpirsch’s fix in #324, it’s again possible to run the Unicode test suite for text rendering engines on OpenType.js.
Expected Behavior
All test cases should pass.
Current Behavior
Currently, OpenType.js is failing 62 test cases. See test report.
Possible Solution
Consider fixing at least CMAP-1, CMAP-2, and all the GPOS and GSUB cases. For inspiration, have a look at fontkit, another OpenType implementation in JavaScript, which is passing most tests in the test suite (see test report).
Steps to Reproduce
See README for the test suite. Until OpenType.js cuts its next release, you’ll need to manually patch @fpirsch’s fix from #324 into node_modules/opentype.js/bin/test-render
.
Hi @brawer Thanks for reporting that!
I merged PR #324 but a new release on npm is still needed I guess?
@Jolg42 last release was several months ago, a whole lot of bugs have been fixed since. It would be nice to have a new release :-)
@fpirsch @brawer 0.8.0 is out!
Updated test report is here. Happy debugging!
Actually bin/test-render
has its own text rendering function which doesn't handle any font feature. It uses opentype.js only to get individual glyph SVG paths. This is why most tests fail.
Here’s a fresh test report for OpenType.js 0.10.0. @fpirsch, you wrote that most tests fail because of https://github.com/nodebox/opentype.js/blob/master/bin/test-render — what specifically needs to be fixed there?
Hi @brawer !
From what I recall, the problem is that the main function renderSVG()
in this file just concatenates glyph.path.toSVG()
results on each glyph independently. This of course leaves out kerning and ligatures.
It should render the text globally with something like Font.getPath(text, x, y, fontSize, options).toSVG()
.
But won’t Font.getPath(text, x, y, fontSize, options)
return one single path for the entire string? For the Unicode test suite, we’d need output in this form, with <symbol>
and <use>
elements in the SVG:
<?xml version="1.0" encoding="UTF-8"?>
<svg version="1.1"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
viewBox="0 -120 1446 1200">
<symbol id="Foo-5/6.uni2269" overflow="visible"><path d="M100,334 L623,563 L623,619 L100,880 L100,793 L518,594 L100,420 Z M100,208 L622,208 L622,287 L100,287 Z M100,38 L622,38 L622,117 L100,117 Z M282,-93 L508,379 L436,413 L211,-59 Z"/></symbol>
<use xlink:href="#Foo-5/6.uni2269" x="0" y="0"/>
<use xlink:href="#Foo-5/6.uni2269" x="723" y="0"/>
</svg>
when calling the renderering command like this:
./bin/test-render --font=fonts/TestCMAP14.otf --testcase=Foo-5/6 --render=≩≩
In any case, if you could fix it (in whatever way), that would help to find bugs in OpenType.js. (Apologies for not jumping into the OpenType.js codebase, but I’m just maintaining the test suite at Unicode; I’m not really working on OpenType.js myself).
I guess this is why @fdb did it this way in the first place. Maybe Font.getPath
should be modified to output separate paths.
I guess this is why @fdb did it this way in the first place. Maybe
Font.getPath
should be modified to output separate paths.
We already have Font.prototype.getPaths()
, which returns an array of glyph paths - shouldn't that be enough?
In #568 I improved the SVG rendering of the test script, so that glyph substitution and positioning should now work exactly like when drawing on a canvas. (font.forEachGlyph()
was what we needed)
Now we pass 69 Tests, and all tests still failing should really be cases that we don't support or handle incorrectly right now (Note that sometimes the paths are just off by a few pixels, so they look like they should pass, but are still actually incorrect): Connum/opentype.js:optimize-svg#7e4de2c (passing: 69, failing: 676)**
Nice!
In your GPOS
handling, consider implementing mark-to-base and mark-to-mark attachment. This is also used by Latin fonts, not just “exotic” writing systems. Likewise, fixing test case GSUB-2
will also improve the rendering for Latin fonts; you wouldn’t need to implement anything specific to Ethiopic, just make the OpenType handling more complete.
To pass test cases CMAP-1
and CMAP-2
, you’d need to implement cmap type 14 for Unicode Variation Sequences. This isn’t super commonly used, but it is a general Unicode mechanism.
In your
GPOS
handling, consider implementing mark-to-base and mark-to-mark
There is already a PR for this that's being worked on.
In your
GPOS
handling, consider implementing mark-to-base and mark-to-markThere is already a PR for this that's being worked on.
see #557