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

gasp table #595

Merged
merged 2 commits into from
Jul 31, 2023
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
5 changes: 5 additions & 0 deletions src/opentype.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import _name from './tables/name.js';
import os2 from './tables/os2.js';
import post from './tables/post.js';
import meta from './tables/meta.js';
import gasp from './tables/gasp.js';
/**
* The opentype library.
* @namespace opentype
Expand Down Expand Up @@ -338,6 +339,10 @@ function parseBuffer(buffer, opt={}) {
case 'meta':
metaTableEntry = tableEntry;
break;
case 'gasp':
table = uncompressTable(data, tableEntry);
font.tables.gasp = gasp.parse(table.data, table.offset);
break;
}
}

Expand Down
46 changes: 46 additions & 0 deletions src/tables/gasp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// The `gasp` table contains global information about the font.
// https://learn.microsoft.com/de-de/typography/opentype/spec/gasp

import check from '../check.js';
import parse from '../parse.js';
import table from '../table.js';

//const GASP_SYMMETRIC_GRIDFIT = 0x0004
//const GASP_SYMMETRIC_SMOOTHING = 0x0008
//const GASP_DOGRAY = 0x0002
//const GASP_GRIDFIT = 0x0001

// Parse the `gasp` table
function parseGaspTable(data, start) {
const gasp = {};
const p = new parse.Parser(data, start);
gasp.version = p.parseUShort();
check.argument(gasp.version <= 0x0001, 'Unsupported gasp table version.');
gasp.numRanges = p.parseUShort();
gasp.gaspRanges = [];
for (let i = 0; i < gasp.numRanges; i++) {
gasp.gaspRanges[i] = {
rangeMaxPPEM: p.parseUShort(),
rangeGaspBehavior: p.parseUShort(),
};
}
return gasp;
}


function makeGaspTable(gasp) {
const result = new table.Table('gasp', [
{name: 'version', type: 'USHORT', value: 0x0001},
{name: 'numRanges', type: 'USHORT', value: gasp.numRanges},
]);

for (let i in gasp.numRanges) {
result.fields.push({name: 'rangeMaxPPEM', type: 'USHORT', value: gasp.numRanges[i].rangeMaxPPEM});
result.fields.push({name: 'rangeGaspBehavior', type: 'USHORT', value: gasp.numRanges[i].rangeGaspBehavior});
}

return result;
}

export default { parse: parseGaspTable, make: makeGaspTable };

6 changes: 6 additions & 0 deletions src/tables/sfnt.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import cpal from './cpal.js';
import fvar from './fvar.js';
import stat from './stat.js';
import avar from './avar.js';
import gasp from './gasp.js';

function log2(v) {
return Math.log(v) / Math.log(2) | 0;
Expand Down Expand Up @@ -318,6 +319,7 @@ function fontToSfntTable(font) {

// we have to handle fvar before name, because it may modify name IDs
const fvarTable = font.tables.fvar ? fvar.make(font.tables.fvar, font.names) : undefined;
const gaspTable = font.tables.gasp ? gasp.make(font.tables.gasp) : undefined;

const languageTags = [];
const nameTable = _name.make(names, languageTags);
Expand Down Expand Up @@ -371,6 +373,10 @@ function fontToSfntTable(font) {
tables.push(metaTable);
}

if (gaspTable) {
tables.push(gaspTable);
}

const sfntTable = makeSfntTable(tables);

// Compute the font's checkSum and store it in head.checkSumAdjustment.
Expand Down
32 changes: 32 additions & 0 deletions test/tables/gasp.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import assert from 'assert';
import { Font, Path, Glyph, parse, load} from '../../src/opentype.js';
import { readFileSync } from 'fs';
const loadSync = (url, opt) => parse(readFileSync(url), opt);

describe('tables/gasp.js', function () {
const font = loadSync('./test/fonts/Roboto-Black.ttf');

it('can parse gasp table version', function() {
assert.equal(font.tables.gasp.version, 1);
});
it('can parse gasp table numRanges', function() {
assert.equal(font.tables.gasp.numRanges, 2);
});

it('can parse gasp table numRanges 0 rangeMaxPPEM', function() {
assert.equal(font.tables.gasp.gaspRanges[0].rangeMaxPPEM, 8); // default value
});

it('can parse gasp table numRanges 0 rangeGaspBehavior', function() {
assert.equal(font.tables.gasp.gaspRanges[0].rangeGaspBehavior, 0x0002); //GASP_DOGRAY = 0x0002
});

it('can parse gasp table numRanges 1 rangeMaxPPEM', function() {
assert.equal(font.tables.gasp.gaspRanges[1].rangeMaxPPEM, 0xFFFF); // default value
});

it('can parse gasp table numRanges 1 rangeGaspBehavior', function() {
assert.equal(font.tables.gasp.gaspRanges[1].rangeGaspBehavior, 0x0001 + 0x0002 + 0x0004 + 0x0008); // all flags set = 15
});

});