Skip to content
Open
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
8 changes: 2 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,11 @@
"terser": "terser lib-font.browser.js -o lib-font.browser.js",
"test:browser": "run-p test:server test:playwright",
"test:cleanup": "rm -rf ./test-results",
"test:node:jest": "npm run test:jest -- ./testing/node/",
"test:node:native": "node --test \"./testing/native-node/**/*.js\"",
"test:jest": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --verbose=false",
"test:node": "node --test \"./testing/node/**/*.test.js\" \"./testing/native-node/**/*.js\"",
"test:manual": "http-server -o testing/manual/index.html",
"test:playwright": "playwright test ./testing/browser/playwright.test.js",
"test:server": "node ./testing/browser/server.js",
"test": "run-s clean test:node:jest test:node:native bundle test:browser test:cleanup"
"test": "run-s clean test:node bundle test:browser test:cleanup"
},
"repository": {
"type": "git",
Expand All @@ -45,10 +43,8 @@
"homepage": "https://github.com/Pomax/lib-font#readme",
"devDependencies": {
"@playwright/test": "^1.56.1",
"cross-env": "^7.0.2",
"express": "^4.17.1",
"http-server": "^0.12.3",
"jest": "^26.6.3",
"npm-run-all": "^4.1.5",
"open-cli": "^6.0.1",
"prettier": "^2.1.1",
Expand Down
28 changes: 27 additions & 1 deletion src/opentype/tables/simple/name.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ import { Parser } from "../../../parser.js";
import { SimpleTable } from "../simple-table.js";
import lazy from "../../../lazy.js";

const decoders = {
mac: new TextDecoder(`macintosh`),
shiftJIS: new TextDecoder(`shift-jis`),
big5: new TextDecoder(`big5`),
};

/**
* The OpenType `name` table.
*
Expand Down Expand Up @@ -38,7 +44,27 @@ class name extends SimpleTable {
*/
get(nameID) {
let record = this.nameRecords.find((record) => record.nameID === nameID);
if (record) return record.string;
if (!record) return;

const { platformID, encodingID, string } = record;
const bytes = new Uint8Array(
Array.from(string).map((s) => s.codePointAt(0))
);

if (platformID === 1) {
return decoders.mac.decode(bytes);
}

if (platformID === 3) {
if (encodingID === 2) {
return decoders.shiftJIS.decode(bytes);
}
if (encodingID === 4) {
return decoders.big5.decode(bytes);
}
}

return string;
}
}

Expand Down
6 changes: 2 additions & 4 deletions testing/manual/custom/issue-85.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import fs from "fs";
import { Font } from "../../../lib-font.js";

const font = new Font("testfont");
Expand All @@ -7,6 +6,5 @@ font.src = "../../../fonts/IBMPlexSansThai-Light.ttf";
font.onload = (evt) => {
let font = evt.detail.font;
const { name } = font.opentype.tables;
console.log(name);
fs.writeFileSync(`test.out`, `name: ${name.get(9)}`, `utf-8`);
};
console.log(name, name.get(9));
};
1 change: 0 additions & 1 deletion testing/manual/custom/test.out

This file was deleted.

24 changes: 12 additions & 12 deletions testing/manual/index.html
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<!doctype html>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>LibFont unit tests</title>
<script src="/lib/inflate.js" defer></script>
<script src="/lib/unbrotli.js" defer></script>
<script src="/lib-font.js" type="module" defer></script>
<script src="./index.js" type="module" defer></script>
</head>
<body>
<h1>Please open dev tools for now</h1>
</body>
<head>
<meta charset="utf-8" />
<title>LibFont unit tests</title>
<script src="/lib/inflate.js" defer></script>
<script src="/lib/unbrotli.js" defer></script>
<script src="/lib-font.js" type="module" defer></script>
<script src="./index.js" type="module" defer></script>
</head>
<body>
<h1>Please open dev tools for now</h1>
</body>
</html>
18 changes: 10 additions & 8 deletions testing/node/athena.ruby.test.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import fs from "node:fs";
import { describe, test, before } from "node:test";
import assert from "node:assert";
import { Font } from "../../lib-font.js";
import { testGSUB } from "./gsub/test-gsub.js";

const font = new Font("athena ruby");

describe("Basic font testing", () => {
beforeAll((done) => {
font.onerror = (err) => {
throw err;
};
font.onload = async () => done();
font.src = "./fonts/AthenaRuby_b018.ttf";
});
before(() => new Promise((resolve, reject) => {
font.onerror = (err) => reject(err);
font.onload = () => resolve();
const buffer = fs.readFileSync("./fonts/AthenaRuby_b018.ttf");
font.fromDataBuffer(Uint8Array.from(buffer).buffer, "AthenaRuby_b018.ttf");
}));

test("font loaded", () => {
expect(font.opentype).toBeDefined();
assert.ok(font.opentype !== undefined);
});

test("GSUB format 3 variant access", () => {
Expand Down
20 changes: 11 additions & 9 deletions testing/node/gsub/issue-113/gsub.test.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import fs from "node:fs";
import { describe, test, before } from "node:test";
import assert from "node:assert";
import { Font } from "../../../../lib-font.js";

const font = new Font("GSUB type 7 redirect testing");

describe("GSUB type 7 checks", () => {
beforeAll(async (done) => {
font.onerror = (err) => {
throw err;
};
font.onload = async () => done();
font.src = `./fonts/Lato-Regular.ttf`;
});
before(() => new Promise((resolve, reject) => {
font.onerror = (err) => reject(err);
font.onload = () => resolve();
const buffer = fs.readFileSync("./fonts/Lato-Regular.ttf");
font.fromDataBuffer(Uint8Array.from(buffer).buffer, "Lato-Regular.ttf");
}));

test("font loaded", () => {
expect(font.opentype).toBeDefined();
assert.ok(font.opentype !== undefined);
});

test("has all expected type 7 redirects", () => {
Expand Down Expand Up @@ -41,7 +43,7 @@ describe("GSUB type 7 checks", () => {
});
});

expect(sequence.slice(0,30)).toEqual([
assert.deepStrictEqual(sequence.slice(0,30), [
[26, 7, "dflt", 0, 6, 3],
[26, 7, "dflt", 1, 6, 3],
[28, 7, "dflt", 0, 6, 3],
Expand Down
34 changes: 18 additions & 16 deletions testing/node/gsub/issue-153/gsub.test.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import fs from "node:fs";
import { describe, test, before } from "node:test";
import assert from "node:assert";
import { Font } from "../../../../lib-font.js";

const font = new Font("GSUB type 6 subformat 2 testing");

describe("GSUB 6.2 checks", () => {
beforeAll(async (done) => {
font.onerror = (err) => {
throw err;
};
font.onload = async () => done();
font.src = `./fonts/Bangers-Regular.ttf`;
});
before(() => new Promise((resolve, reject) => {
font.onerror = (err) => reject(err);
font.onload = () => resolve();
const buffer = fs.readFileSync("./fonts/Bangers-Regular.ttf");
font.fromDataBuffer(Uint8Array.from(buffer).buffer, "Bangers-Regular.ttf");
}));

test("font loaded", () => {
expect(font.opentype).toBeDefined();
assert.ok(font.opentype !== undefined);
});

test("has all expected type 7 redirects", () => {
Expand Down Expand Up @@ -44,7 +46,7 @@ describe("GSUB 6.2 checks", () => {
});
});

expect(sequence.slice(0, 30)).toEqual([
assert.deepStrictEqual(sequence.slice(0, 30), [
[0, 1, "dflt", 0, 1, 2],
[1, 3, "dflt", 0, 3, 1],
[20, 1, "dflt", 0, 1, 2],
Expand Down Expand Up @@ -79,7 +81,7 @@ describe("GSUB 6.2 checks", () => {

// I have no idea if this is correct atm
const lookup6dot2 = subtables[4];
expect(lookup6dot2).toEqual({
assert.deepStrictEqual({...lookup6dot2}, {
type: 6,
format: 2,
coverageOffset: 432,
Expand All @@ -92,14 +94,14 @@ describe("GSUB 6.2 checks", () => {

// I have no idea if this is correct atm
const classSet = lookup6dot2.getChainSubClassSet(1);
expect(classSet).toEqual({
assert.deepStrictEqual({...classSet}, {
chainSubClassRuleCount: 1,
chainSubClassRuleOffsets: [512],
});

// I have no idea if this is correct atm
const subclass = classSet.getSubClass(0);
expect(subclass).toEqual({
assert.deepStrictEqual({...subclass, substLookupRecords: subclass.substLookupRecords.map(r => ({...r}))}, {
backtrackGlyphCount: 0,
backtrackSequence: [],
inputGlyphCount: 1,
Expand All @@ -123,9 +125,9 @@ describe("GSUB 6.2 checks", () => {

const inputClassDef = subtable.getInputClassDef();

expect(inputClassDef.classFormat).toBe(2);
assert.strictEqual(inputClassDef.classFormat, 2);

expect(inputClassDef.classRangeRecords).toEqual([
assert.deepStrictEqual(inputClassDef.classRangeRecords.map(r => ({...r})), [
{ startGlyphID: 272, endGlyphID: 272, class: 2 }, // i
{ startGlyphID: 288, endGlyphID: 288, class: 1 }, // j
]);
Expand All @@ -139,7 +141,7 @@ describe("GSUB 6.2 checks", () => {
const backtrackClassDef = subtable.getBacktrackClassDef();

// Bangers has no backtrack chars for this lookup
expect(backtrackClassDef.classRangeRecords).toEqual([]);
assert.deepStrictEqual(backtrackClassDef.classRangeRecords, []);
});

test("getLookaheadClassDef returns multiple definitions", () => {
Expand All @@ -164,7 +166,7 @@ describe("GSUB 6.2 checks", () => {
// hookabovecomb
// uni030F
// uni0312
expect(lookaheadClassDef.classRangeRecords).toEqual([
assert.deepStrictEqual(lookaheadClassDef.classRangeRecords.map(r => ({...r})), [
{ startGlyphID: 525, endGlyphID: 529, class: 1 },
{ startGlyphID: 531, endGlyphID: 538, class: 1 },
{ startGlyphID: 540, endGlyphID: 540, class: 1 },
Expand Down
20 changes: 10 additions & 10 deletions testing/node/gsub/test-gsub.js
Original file line number Diff line number Diff line change
@@ -1,52 +1,52 @@
import { expect } from "@jest/globals";
import assert from "node:assert";
import { profiles } from "../font-profiles/profiles.js";

function testGSUB(font, tests) {
const expectation = profiles[font.name];

const { cmap, name, GSUB } = font.opentype.tables;

expect(GSUB).toBeDefined();
expect(cmap).toBeDefined();
expect(name).toBeDefined();
assert.ok(GSUB !== undefined);
assert.ok(cmap !== undefined);
assert.ok(name !== undefined);

let scripts = GSUB.getSupportedScripts();
expect(scripts).toEqual(Object.keys(expectation));
assert.deepStrictEqual(scripts, Object.keys(expectation));

scripts.forEach((script) => {
tests.script.forEach(fn => fn(script));

let langsys = GSUB.getSupportedLangSys(script);

expect(langsys).toEqual(expectation[script].langsys);
assert.deepStrictEqual(langsys, expectation[script].langsys);

langsys.forEach((lang) => {
let langSysTable = GSUB.getLangSysTable(script, lang);
let features = GSUB.getFeatures(langSysTable);
let featureCount = features.length;

expect(featureCount).toEqual(expectation[script].features[lang].length);
assert.deepStrictEqual(featureCount, expectation[script].features[lang].length);

features.forEach((feature) => {
tests.feature.forEach(fn => fn(feature));

const lookupIDs = feature.lookupListIndices;

const test = {
const actual = {
script,
lang,
feature: feature.featureTag,
lookupIDs
};

const match = {
const expected = {
script,
lang,
feature: feature.featureTag,
lookupIDs: expectation[script].features[lang].lookups[feature.featureTag]
};

expect(test).toEqual(match);
assert.deepStrictEqual(actual, expected);

lookupIDs.forEach((id) => {
const lookup = GSUB.getLookup(id);
Expand Down
27 changes: 27 additions & 0 deletions testing/node/ibm.plex.sans.thai.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import fs from "node:fs";
import { describe, test, before } from "node:test";
import assert from "node:assert";
import { Font } from "../../lib-font.js";

const font = new Font("ibm plex sans thai");

describe("IBM Plex Sans Thai", () => {
before(() => new Promise((resolve, reject) => {
font.onerror = (err) => reject(err);
font.onload = () => resolve();
const buffer = fs.readFileSync("./fonts/IBMPlexSansThai-Light.ttf");
font.fromDataBuffer(Uint8Array.from(buffer).buffer, "IBMPlexSansThai-Light.ttf");
}));

test("font loaded", () => {
assert.ok(font.opentype !== undefined);
});

test("name table ID 9 contains expected designer string", () => {
const { name } = font.opentype.tables;
assert.strictEqual(
name.get(9),
"Mike Abbink, Paul van der Laan, Pieter van Rosmalen, Ben Mitchell, Mark Frömberg"
);
});
});
Loading
Loading