summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/font-access/resources/font-test-utils.js
blob: e183b35bfa077a41f988f585fedec1264e19a877 (plain)
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);
  });
}