diff --git a/package.json b/package.json
index bb2a539..7d81776 100644
--- a/package.json
+++ b/package.json
@@ -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",
@@ -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",
diff --git a/src/opentype/tables/simple/name.js b/src/opentype/tables/simple/name.js
index ec3be87..d73940e 100644
--- a/src/opentype/tables/simple/name.js
+++ b/src/opentype/tables/simple/name.js
@@ -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.
*
@@ -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;
}
}
diff --git a/testing/manual/custom/issue-85.js b/testing/manual/custom/issue-85.js
index da2f668..15b0be5 100644
--- a/testing/manual/custom/issue-85.js
+++ b/testing/manual/custom/issue-85.js
@@ -1,4 +1,3 @@
-import fs from "fs";
import { Font } from "../../../lib-font.js";
const font = new Font("testfont");
@@ -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`);
-};
\ No newline at end of file
+ console.log(name, name.get(9));
+};
diff --git a/testing/manual/custom/test.out b/testing/manual/custom/test.out
deleted file mode 100644
index a1d4b50..0000000
--- a/testing/manual/custom/test.out
+++ /dev/null
@@ -1 +0,0 @@
-name: Mike Abbink, Paul van der Laan, Pieter van Rosmalen, Ben Mitchell, Mark Frmberg
\ No newline at end of file
diff --git a/testing/manual/index.html b/testing/manual/index.html
index bf13627..2046f6e 100644
--- a/testing/manual/index.html
+++ b/testing/manual/index.html
@@ -1,14 +1,14 @@
-
+
-
-
- LibFont unit tests
-
-
-
-
-
-
- Please open dev tools for now
-
+
+
+ LibFont unit tests
+
+
+
+
+
+
+ Please open dev tools for now
+
diff --git a/testing/node/athena.ruby.test.js b/testing/node/athena.ruby.test.js
index b1bd4d2..39c5e5a 100644
--- a/testing/node/athena.ruby.test.js
+++ b/testing/node/athena.ruby.test.js
@@ -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", () => {
diff --git a/testing/node/gsub/issue-113/gsub.test.js b/testing/node/gsub/issue-113/gsub.test.js
index 91ee080..b71845e 100644
--- a/testing/node/gsub/issue-113/gsub.test.js
+++ b/testing/node/gsub/issue-113/gsub.test.js
@@ -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", () => {
@@ -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],
diff --git a/testing/node/gsub/issue-153/gsub.test.js b/testing/node/gsub/issue-153/gsub.test.js
index 86f7f77..a5f107b 100644
--- a/testing/node/gsub/issue-153/gsub.test.js
+++ b/testing/node/gsub/issue-153/gsub.test.js
@@ -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", () => {
@@ -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],
@@ -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,
@@ -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,
@@ -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
]);
@@ -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", () => {
@@ -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 },
diff --git a/testing/node/gsub/test-gsub.js b/testing/node/gsub/test-gsub.js
index dcbf32f..92bbd32 100644
--- a/testing/node/gsub/test-gsub.js
+++ b/testing/node/gsub/test-gsub.js
@@ -1,4 +1,4 @@
-import { expect } from "@jest/globals";
+import assert from "node:assert";
import { profiles } from "../font-profiles/profiles.js";
function testGSUB(font, tests) {
@@ -6,47 +6,47 @@ function testGSUB(font, tests) {
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);
diff --git a/testing/node/ibm.plex.sans.thai.test.js b/testing/node/ibm.plex.sans.thai.test.js
new file mode 100644
index 0000000..995a7f4
--- /dev/null
+++ b/testing/node/ibm.plex.sans.thai.test.js
@@ -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"
+ );
+ });
+});
diff --git a/testing/node/issue-114/flaticon.test.js b/testing/node/issue-114/flaticon.test.js
index 191e24c..efd7b5f 100644
--- a/testing/node/issue-114/flaticon.test.js
+++ b/testing/node/issue-114/flaticon.test.js
@@ -1,28 +1,30 @@
+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("flaticon");
describe("Basic font testing", () => {
- beforeAll((done) => {
- font.onerror = (err) => {
- throw err;
- };
- font.onload = async () => done();
- font.src = "./fonts/issue-114/Flaticon.woff2";
- });
+ before(() => new Promise((resolve, reject) => {
+ font.onerror = (err) => reject(err);
+ font.onload = () => resolve();
+ const buffer = fs.readFileSync("./fonts/issue-114/Flaticon.woff2");
+ font.fromDataBuffer(Uint8Array.from(buffer).buffer, "Flaticon.woff2");
+ }));
test("font loaded", () => {
- expect(font.opentype).toBeDefined();
+ assert.ok(font.opentype !== undefined);
});
test("has name table", () => {
const { name } = font.opentype.tables;
- expect(name).toBeDefined();
- expect(name.count).toBe(14);
+ assert.ok(name !== undefined);
+ assert.strictEqual(name.count, 14);
const ID3 = `FontForge 2.0 : Flaticon : 21-12-2019`;
- expect(name.get(3)).toBe(ID3);
+ assert.strictEqual(name.get(3), ID3);
});
});
diff --git a/testing/node/mehr.nastaliq.test.js b/testing/node/mehr.nastaliq.test.js
index 2a53da3..b2366d1 100644
--- a/testing/node/mehr.nastaliq.test.js
+++ b/testing/node/mehr.nastaliq.test.js
@@ -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("mehr nastaliq");
describe("Basic font testing", () => {
- beforeAll((done) => {
- font.onerror = (err) => {
- throw err;
- };
- font.onload = async () => done();
- font.src = "./fonts/MehrNastaliqWeb-Regular.ttf";
- });
+ before(() => new Promise((resolve, reject) => {
+ font.onerror = (err) => reject(err);
+ font.onload = () => resolve();
+ const buffer = fs.readFileSync("./fonts/MehrNastaliqWeb-Regular.ttf");
+ font.fromDataBuffer(Uint8Array.from(buffer).buffer, "MehrNastaliqWeb-Regular.ttf");
+ }));
test("font loaded", () => {
- expect(font.opentype).toBeDefined();
+ assert.ok(font.opentype !== undefined);
});
test("GSUB format 6/8 functionality", () => {
diff --git a/testing/node/source.code.pro.test.js b/testing/node/source.code.pro.test.js
index 5932247..6e8e081 100644
--- a/testing/node/source.code.pro.test.js
+++ b/testing/node/source.code.pro.test.js
@@ -1,3 +1,6 @@
+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";
@@ -5,16 +8,15 @@ const font = new Font("source code pro");
let letterFor = function(){};
describe("Basic font testing", () => {
- beforeAll((done) => {
- font.onerror = (err) => {
- throw err;
- };
- font.onload = async () => done();
- font.src = "./fonts/SourceCodePro/SourceCodePro-Regular.ttf";
- });
+ before(() => new Promise((resolve, reject) => {
+ font.onerror = (err) => reject(err);
+ font.onload = () => resolve();
+ const buffer = fs.readFileSync("./fonts/SourceCodePro/SourceCodePro-Regular.ttf");
+ font.fromDataBuffer(Uint8Array.from(buffer).buffer, "SourceCodePro-Regular.ttf");
+ }));
test("font loaded", () => {
- expect(font.opentype).toBeDefined();
+ assert.ok(font.opentype !== undefined);
letterFor = function(glyphid) {
let reversed = font.opentype.tables.cmap.reverse(glyphid);
@@ -23,22 +25,22 @@ describe("Basic font testing", () => {
});
test("Glyph support", () => {
- expect(font.supports(`f`)).toBe(true);
- expect(font.supports(`i`)).toBe(true);
- expect(font.supports(String.fromCharCode(0xffff))).toBe(false);
+ assert.strictEqual(font.supports(`f`), true);
+ assert.strictEqual(font.supports(`i`), true);
+ assert.strictEqual(font.supports(String.fromCharCode(0xffff)), false);
});
test("HEAD table", () => {
const head = font.opentype.tables.head;
- expect(head).toBeDefined();
-
- expect(head.magicNumber).toBe(1594834165);
- expect(head.fontDirectionHint).toBe(2);
- expect(head.unitsPerEm).toBe(1000);
- expect(head.xMin).toBe(-193);
- expect(head.xMax).toBe(793);
- expect(head.yMin).toBe(-454);
- expect(head.yMax).toBe(1060);
+ assert.ok(head !== undefined);
+
+ assert.strictEqual(head.magicNumber, 1594834165);
+ assert.strictEqual(head.fontDirectionHint, 2);
+ assert.strictEqual(head.unitsPerEm, 1000);
+ assert.strictEqual(head.xMin, -193);
+ assert.strictEqual(head.xMax, 793);
+ assert.strictEqual(head.yMin, -454);
+ assert.strictEqual(head.yMax, 1060);
});
test("GSUB table", () => {