diff options
Diffstat (limited to 'testing/web-platform/tests/font-access/resources')
3 files changed, 205 insertions, 0 deletions
diff --git a/testing/web-platform/tests/font-access/resources/font-asserts.js b/testing/web-platform/tests/font-access/resources/font-asserts.js new file mode 100644 index 0000000000..7094d8f0bf --- /dev/null +++ b/testing/web-platform/tests/font-access/resources/font-asserts.js @@ -0,0 +1,38 @@ +'use strict'; + +function assert_font_equals(actualFont, expectedFont) { + assert_equals( + actualFont.postscriptName, expectedFont.postscriptName, + `${actualFont.postscriptName}: postscriptName should match`); + assert_equals( + actualFont.fullName, expectedFont.fullName, + `${actualFont.postscriptName}: fullName should match`); + assert_equals( + actualFont.family, expectedFont.family, + `${actualFont.postscriptName}: family should match`); + assert_equals( + actualFont.style, expectedFont.style, + `${actualFont.postscriptName}: style should match`); +} + +function assert_font_has_tables(fontName, actualTables, expectedTables) { + for (const expectedTable of expectedTables) { + assert_equals( + expectedTable.length, 4, 'Table names are always 4 characters long.'); + assert_true( + actualTables.has(expectedTable), + `Font ${fontName} did not have required table ${expectedTable}.`); + assert_greater_than( + actualTables.get(expectedTable).size, 0, + `Font ${fontName} has table ${expectedTable} of size 0.`); + } +} + +function assert_version_info(versionTag) { + // Spec: https://docs.microsoft.com/en-us/typography/opentype/spec/otff#organization-of-an-opentype-font + assert_true(versionTag === '\x00\x01\x00\x00' || + versionTag === 'true' || + versionTag === 'typ1' || + versionTag === 'OTTO', + `Invalid sfnt version tag: ${versionTag}`); +}
\ No newline at end of file diff --git a/testing/web-platform/tests/font-access/resources/font-data.js b/testing/web-platform/tests/font-access/resources/font-data.js new file mode 100644 index 0000000000..f8e7023e67 --- /dev/null +++ b/testing/web-platform/tests/font-access/resources/font-data.js @@ -0,0 +1,66 @@ +'use strict'; + +// The OpenType spec mentions that the follow tables are required for a font to +// function correctly. We'll have all the tables listed except for OS/2, which +// is not present in all fonts on Mac OS. +// https://docs.microsoft.com/en-us/typography/opentype/spec/otff#font-tables +const BASE_TABLES = [ + 'cmap', + 'head', + 'hhea', + 'hmtx', + 'maxp', + 'name', + 'post', +]; + +const MAC_FONTS = new Map([ + ['Monaco', { + postscriptName: 'Monaco', + fullName: 'Monaco', + family: 'Monaco', + style: 'Regular', + }], + ['Menlo-Regular', { + postscriptName: 'Menlo-Regular', + fullName: 'Menlo Regular', + family: 'Menlo', + style: 'Regular', + }], +]); + +const WIN_FONTS = new Map([ + ['Verdana', { + postscriptName: 'Verdana', + fullName: 'Verdana', + family: 'Verdana', + style: 'Regular', + }], +]); + +const LINUX_FONTS = new Map([ + ['Ahem', { + postscriptName: 'Ahem', + fullName: 'Ahem', + family: 'Ahem', + style: 'Regular', + }], +]); + +// Returns a map of known system fonts, mapping a font's postscript name to +// FontData. +function getTestData() { + let output = undefined; + if (navigator.platform.indexOf("Win") !== -1) { + output = WIN_FONTS; + } else if (navigator.platform.indexOf("Mac") !== -1) { + output = MAC_FONTS; + } else if (navigator.platform.indexOf("Linux") !== -1) { + output = LINUX_FONTS; + } + + assert_not_equals( + output, undefined, 'Cannot get test set due to unsupported platform.'); + + return output; +}
\ No newline at end of file diff --git a/testing/web-platform/tests/font-access/resources/font-test-utils.js b/testing/web-platform/tests/font-access/resources/font-test-utils.js new file mode 100644 index 0000000000..e183b35bfa --- /dev/null +++ b/testing/web-platform/tests/font-access/resources/font-test-utils.js @@ -0,0 +1,101 @@ +'use strict'; + +// Filters an array of FontData by font names. Used to reduce down +// the size of test data. +function filterFonts(fonts, filter) { + const filteredFont = []; + for (const font of fonts) { + if (filter.includes(font.postscriptName)) { + filteredFont.push(font); + } + } + return filteredFont; +} + +async function parseFontData(fontBlob) { + // Parsed result to be returned. + const fontInfo = {}; + + try { + // Parse the version info. + fontInfo.versionTag = await getTag(fontBlob, 0); + // Parse the table data. + const numTables = await getUint16(fontBlob, 4); + [fontInfo.tables, fontInfo.tableMeta] = + await getTableData(fontBlob, numTables); + } catch (error) { + throw `Error parsing font table: ${error.message}`; + } + + return fontInfo; +} + +async function getTableData(fontBlob, numTables) { + const dataMap = new Map(); + const metaMap = new Map(); + let blobOffset = 12; + + for (let i = 0; i < numTables; i++) { + const tag = await getTag(fontBlob, blobOffset); + const checksum = await getUint32(fontBlob, blobOffset + 4); + const offset = await getUint32(fontBlob, blobOffset + 8); + const size = await getUint32(fontBlob, blobOffset + 12); + const tableBlob = fontBlob.slice(offset, offset + size); + dataMap.set(tag, tableBlob); + metaMap.set(tag, {checksum, offset, size}); + blobOffset += 16; + } + + return [dataMap, metaMap]; +} + +async function getTag(blob, offset) { + return (new TextDecoder).decode( + await blob.slice(offset, offset + 4).arrayBuffer()); +} + +async function getUint16(blob, offset) { + const slice = blob.slice(offset, offset + 2); + const buf = await slice.arrayBuffer(); + const dataView = new DataView(buf); + return dataView.getUint16(0); +} + +async function getUint32(blob, offset) { + const slice = blob.slice(offset, offset + 4); + const buf = await slice.arrayBuffer(); + const dataView = new DataView(buf); + return dataView.getUint32(0); +} + +function promiseDocumentReady() { + return new Promise(resolve => { + if (document.readyState === 'complete') { + resolve(); + } + window.addEventListener('load', () => { + resolve(); + }, {once: true}); + }); +} + +function isPlatformSupported() { + if (navigator.platform.indexOf('Mac') !== -1 || + navigator.platform.indexOf('Win') !== -1 || + navigator.platform.indexOf('Linux') !== -1) { + return true; + } + return false; +} + +function font_access_test(test_function, name, properties) { + return promise_test(async (t) => { + if (!isPlatformSupported()) { + await promise_rejects_dom( + t, 'NotSupportedError', self.queryLocalFonts()); + return; + } + await test_driver.set_permission({name: 'local-fonts'}, 'granted'); + await test_function(t, name, properties); + }); +} |