font-test-utils.js (2754B)
1 'use strict'; 2 3 // Filters an array of FontData by font names. Used to reduce down 4 // the size of test data. 5 function filterFonts(fonts, filter) { 6 const filteredFont = []; 7 for (const font of fonts) { 8 if (filter.includes(font.postscriptName)) { 9 filteredFont.push(font); 10 } 11 } 12 return filteredFont; 13 } 14 15 async function parseFontData(fontBlob) { 16 // Parsed result to be returned. 17 const fontInfo = {}; 18 19 try { 20 // Parse the version info. 21 fontInfo.versionTag = await getTag(fontBlob, 0); 22 // Parse the table data. 23 const numTables = await getUint16(fontBlob, 4); 24 [fontInfo.tables, fontInfo.tableMeta] = 25 await getTableData(fontBlob, numTables); 26 } catch (error) { 27 throw `Error parsing font table: ${error.message}`; 28 } 29 30 return fontInfo; 31 } 32 33 async function getTableData(fontBlob, numTables) { 34 const dataMap = new Map(); 35 const metaMap = new Map(); 36 let blobOffset = 12; 37 38 for (let i = 0; i < numTables; i++) { 39 const tag = await getTag(fontBlob, blobOffset); 40 const checksum = await getUint32(fontBlob, blobOffset + 4); 41 const offset = await getUint32(fontBlob, blobOffset + 8); 42 const size = await getUint32(fontBlob, blobOffset + 12); 43 const tableBlob = fontBlob.slice(offset, offset + size); 44 dataMap.set(tag, tableBlob); 45 metaMap.set(tag, {checksum, offset, size}); 46 blobOffset += 16; 47 } 48 49 return [dataMap, metaMap]; 50 } 51 52 async function getTag(blob, offset) { 53 return (new TextDecoder) 54 .decode(await blob.slice(offset, offset + 4).arrayBuffer()); 55 } 56 57 async function getUint16(blob, offset) { 58 const slice = blob.slice(offset, offset + 2); 59 const buf = await slice.arrayBuffer(); 60 const dataView = new DataView(buf); 61 return dataView.getUint16(0); 62 } 63 64 async function getUint32(blob, offset) { 65 const slice = blob.slice(offset, offset + 4); 66 const buf = await slice.arrayBuffer(); 67 const dataView = new DataView(buf); 68 return dataView.getUint32(0); 69 } 70 71 function promiseDocumentReady() { 72 return new Promise(resolve => { 73 if (document.readyState === 'complete') { 74 resolve(); 75 } 76 window.addEventListener('load', () => { 77 resolve(); 78 }, {once: true}); 79 }); 80 } 81 82 function isPlatformSupported() { 83 if (navigator.platform.indexOf('Mac') !== -1 || 84 navigator.platform.indexOf('Win') !== -1 || 85 navigator.platform.indexOf('Linux') !== -1) { 86 return true; 87 } 88 return false; 89 } 90 91 function font_access_test(test_function, name, properties) { 92 return promise_test(async (t) => { 93 if (!isPlatformSupported()) { 94 await promise_rejects_dom(t, 'NotSupportedError', self.queryLocalFonts()); 95 return; 96 } 97 await test_driver.set_permission({name: 'local-fonts'}, 'granted'); 98 await test_function(t, name, properties); 99 }); 100 }