1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
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);
});
}
|