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

Add fontkit engine #35

Merged
merged 1 commit into from
May 2, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
*.o
*.a
*.pyc
node_modules/
build/
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,3 @@
[submodule "src/third_party/raqm/libraqm"]
path = src/third_party/raqm/libraqm
url = https://github.com/HOST-Oman/libraqm.git
[submodule "src/third_party/opentypejs/opentype.js"]
path = src/third_party/opentypejs/opentype.js
url = https://github.com/nodebox/opentype.js.git
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ $ python check.py --output=report.html --engine=FreeStack

## Supported Platforms

Currently, the test suite supports only three OpenType implementations:
Currently, the test suite supports four OpenType implementations:

* With `--engine=FreeStack`, the tests are run on the free/libre
open-source text rendering stack with [FreeType](https://www.freetype.org/),
Expand All @@ -32,7 +32,9 @@ are used by Linux, Android, ChromeOS, and many other systems.
This option will work only if you run the test suite on MacOS X.

* With `--engine=OpenType.js`, the tests are run using [OpenType.js](https://github.com/nodebox/opentype.js).
This option requires Node.js to be installed.

* With `--engine=fontkit`, the tests are run on
[fontkit](http://github.com/devongovett/fontkit), a JavaScript font engine.

If you’d like to test another OpenType implementation, please go ahead.

Expand Down
10 changes: 6 additions & 4 deletions check.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@ class ConformanceChecker:
def __init__(self, engine):
self.engine = engine
if self.engine == 'OpenType.js':
self.command = 'src/third_party/opentypejs/opentype.js/bin/test-render'
self.command = 'node_modules/opentype.js/bin/test-render'
elif self.engine == 'fontkit':
self.command = 'src/third_party/fontkit/render'
else:
self.command = 'build/out/Default/fonttest'
self.datestr = self.make_datestr()
Expand Down Expand Up @@ -144,8 +146,8 @@ def write_report(self, path):


def build(engine):
if engine == 'OpenType.js':
subprocess.check_call(['npm', 'install'], cwd='./src/third_party/opentypejs/opentype.js')
if engine == 'OpenType.js' or engine == 'fontkit':
subprocess.check_call(['npm', 'install'])
else:
subprocess.check_call(
'./src/third_party/gyp/gyp -f make --depth . '
Expand All @@ -158,7 +160,7 @@ def main():
etree.register_namespace('xlink', 'http://www.w3.org/1999/xlink')
parser = argparse.ArgumentParser()
parser.add_argument('--engine',
choices=['FreeStack', 'CoreText', 'DirectWrite', 'OpenType.js'],
choices=['FreeStack', 'CoreText', 'DirectWrite', 'OpenType.js', 'fontkit'],
default='FreeStack')
parser.add_argument('--output', help='path to report file being written')
args = parser.parse_args()
Expand Down
10 changes: 10 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "text-rendering-tests",
"version": "1.0.0",
"description": "OpenType test suite",
"dependencies": {
"fontkit": "^1.5.6",
"iconv-lite": "^0.4.17",
"opentype.js": "^0.7.1"
}
}
2,695 changes: 2,695 additions & 0 deletions reports/fontkit.html

Large diffs are not rendered by default.

76 changes: 76 additions & 0 deletions src/third_party/fontkit/render
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#!/usr/bin/env node

let fontkit = require('fontkit');

// Poor man's argument parser
let argv = {};
for (let arg of process.argv) {
let match = arg.match(/^--(.+)=(.+)$/);
if (match) {
argv[match[1]] = match[2];
}
}

function render() {
let font = fontkit.openSync(argv.font);

if (argv.variation) {
let settings = {};
argv.variation.split(';').forEach(setting => {
let parts = setting.split(':');
settings[parts[0]] = parts[1];
});

font = font.getVariation(settings);
}

let run = font.layout(argv.render);
let gids = {};

let glyphs = run.glyphs.map(glyph => {
if (gids[glyph.id]) return;
gids[glyph.id] = true;

// Get path and normalize
let path = glyph.getScaledPath(1000).mapPoints((x, y) => [Math.floor(x), Math.floor(y)]);
let svgPath = path.toSVG()
.replace(/(\d+) (-?\d+)/g, '$1,$2')
.replace(/(\d)([A-Z])/g, '$1 $2')
.replace(/Z([^\s])/g, 'Z $1');

return (
`<symbol id="${argv.testcase}.${glyph.name || `gid${glyph.id}`}" overflow="visible">` +
`<path d="${svgPath}" />` +
`</symbol>`
);
});

let scale = 1 / font.unitsPerEm * 1000;
let x = 0, y = 0;
let svg = run.glyphs.map((glyph, index) => {
let pos = run.positions[index];
let xPos = Math.round(x + pos.xOffset * scale);
let yPos = Math.round(y + pos.yOffset * scale);
let use = `<use x="${xPos}" y="${yPos}" xlink:href="#${argv.testcase}.${glyph.name || `gid${glyph.id}`}" />`;
x += Math.round(pos.xAdvance * scale);
y += Math.round(pos.yAdvance * scale);
return use;
});

let bbox = [0, font.descent, run.advanceWidth, font.ascent - font.descent].map(x => Math.round(x * scale));

console.log(
'<?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="${bbox.join(' ')}">`,
glyphs.join('\n'),
svg.join('\n'),
'</svg>'
);
}

try {
render();
} catch (e) {
console.error(e.stack);
process.exit(1);
}
1 change: 0 additions & 1 deletion src/third_party/opentypejs/opentype.js
Submodule opentype.js deleted from 220f78