first commit
	
		
			
	
		
	
	
		
	
		
			Some checks failed
		
		
	
	
		
			
				
	
				Types tests / Test (lts/*) (push) Has been cancelled
				
			
		
			
				
	
				Lint / Lint (lts/*) (push) Has been cancelled
				
			
		
			
				
	
				CodeQL / Analyze (javascript) (push) Has been cancelled
				
			
		
			
				
	
				CI / Test (20) (push) Has been cancelled
				
			
		
			
				
	
				CI / Test (22) (push) Has been cancelled
				
			
		
			
				
	
				CI / Test (24) (push) Has been cancelled
				
			
		
		
	
	
				
					
				
			
		
			Some checks failed
		
		
	
	Types tests / Test (lts/*) (push) Has been cancelled
				
			Lint / Lint (lts/*) (push) Has been cancelled
				
			CodeQL / Analyze (javascript) (push) Has been cancelled
				
			CI / Test (20) (push) Has been cancelled
				
			CI / Test (22) (push) Has been cancelled
				
			CI / Test (24) (push) Has been cancelled
				
			This commit is contained in:
		
							
								
								
									
										36
									
								
								test/font/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								test/font/README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
			
		||||
# Font tests
 | 
			
		||||
 | 
			
		||||
The font tests check if PDF.js can read font data correctly. For validation
 | 
			
		||||
the `ttx` tool (from the Python `fonttools` library) is used that can convert
 | 
			
		||||
font data to an XML format that we can easily use for assertions in the tests.
 | 
			
		||||
In the font tests we let PDF.js read font data and pass the PDF.js-interpreted
 | 
			
		||||
font data through `ttx` to check its correctness. The font tests are successful
 | 
			
		||||
if PDF.js can successfully read the font data and `ttx` can successfully read
 | 
			
		||||
the PDF.js-interpreted font data back, proving that PDF.js does not apply any
 | 
			
		||||
transformations that break the font data.
 | 
			
		||||
 | 
			
		||||
## Running the font tests
 | 
			
		||||
 | 
			
		||||
The font tests are run on GitHub Actions using the workflow defined in
 | 
			
		||||
`.github/workflows/font_tests.yml`, but it is also possible to run the font
 | 
			
		||||
tests locally. The current stable versions of the following dependencies are
 | 
			
		||||
required to be installed on the system:
 | 
			
		||||
 | 
			
		||||
- Python 3
 | 
			
		||||
- `fonttools` (see https://pypi.org/project/fonttools and https://github.com/fonttools/fonttools)
 | 
			
		||||
 | 
			
		||||
The recommended way of installing `fonttools` is using `pip` in a virtual
 | 
			
		||||
environment because it avoids having to do a system-wide installation and
 | 
			
		||||
therefore improves isolation, but any other way of installing `fonttools`
 | 
			
		||||
that makes `ttx` available in the `PATH` environment variable also works.
 | 
			
		||||
 | 
			
		||||
Using the virtual environment approach the font tests can be run locally by
 | 
			
		||||
creating and sourcing a virtual environment with `fonttools` installed in
 | 
			
		||||
it before running the font tests:
 | 
			
		||||
    
 | 
			
		||||
```
 | 
			
		||||
python3 -m venv venv
 | 
			
		||||
source venv/bin/activate
 | 
			
		||||
pip install fonttools
 | 
			
		||||
npx gulp fonttest
 | 
			
		||||
```
 | 
			
		||||
							
								
								
									
										18
									
								
								test/font/font_core_spec.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								test/font/font_core_spec.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
			
		||||
import { decodeFontData, ttx, verifyTtxOutput } from "./fontutils.js";
 | 
			
		||||
 | 
			
		||||
describe("font1", function () {
 | 
			
		||||
  const font1_1 = decodeFontData(
 | 
			
		||||
    // eslint-disable-next-line max-len
 | 
			
		||||
    "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"
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  describe("test harness testing", function () {
 | 
			
		||||
    it("returns output", async function () {
 | 
			
		||||
      const output = await ttx(font1_1);
 | 
			
		||||
 | 
			
		||||
      verifyTtxOutput(output);
 | 
			
		||||
      expect(/<ttFont /.test(output)).toEqual(true);
 | 
			
		||||
      expect(/<\/ttFont>/.test(output)).toEqual(true);
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										45
									
								
								test/font/font_fpgm_spec.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								test/font/font_fpgm_spec.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										71
									
								
								test/font/font_os2_spec.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								test/font/font_os2_spec.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										93
									
								
								test/font/font_post_spec.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								test/font/font_post_spec.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										25
									
								
								test/font/font_test.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								test/font/font_test.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
			
		||||
<!DOCTYPE html>
 | 
			
		||||
<html>
 | 
			
		||||
<head>
 | 
			
		||||
  <title>PDF.js font tests</title>
 | 
			
		||||
 | 
			
		||||
  <link rel="stylesheet" type="text/css" href="../../node_modules/jasmine-core/lib/jasmine-core/jasmine.css">
 | 
			
		||||
 | 
			
		||||
  <script src="../../node_modules/jasmine-core/lib/jasmine-core/jasmine.js"></script>
 | 
			
		||||
  <script src="../../node_modules/jasmine-core/lib/jasmine-core/jasmine-html.js"></script>
 | 
			
		||||
 | 
			
		||||
  <script type="importmap">
 | 
			
		||||
    {
 | 
			
		||||
      "imports": {
 | 
			
		||||
        "pdfjs/": "../../src/",
 | 
			
		||||
        "pdfjs-lib": "../../src/pdf.js",
 | 
			
		||||
        "pdfjs-web/": "../../web/",
 | 
			
		||||
        "pdfjs-test/": "../"
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  </script>
 | 
			
		||||
  <script src="jasmine-boot.js" type="module"></script>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										48
									
								
								test/font/fontutils.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								test/font/fontutils.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,48 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2013 Mozilla Foundation
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import { bytesToString, stringToBytes } from "../../src/shared/util.js";
 | 
			
		||||
 | 
			
		||||
function decodeFontData(base64) {
 | 
			
		||||
  const str = atob(base64);
 | 
			
		||||
  return stringToBytes(str);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function encodeFontData(data) {
 | 
			
		||||
  const str = bytesToString(data);
 | 
			
		||||
  return btoa(str);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function ttx(data) {
 | 
			
		||||
  const response = await fetch("/ttx", {
 | 
			
		||||
    method: "POST",
 | 
			
		||||
    body: encodeFontData(data),
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  if (!response.ok) {
 | 
			
		||||
    throw new Error(response.statusText);
 | 
			
		||||
  }
 | 
			
		||||
  return response.text();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
function verifyTtxOutput(output) {
 | 
			
		||||
  const m = /^<error>(.*?)<\/error>/.exec(output);
 | 
			
		||||
  if (m) {
 | 
			
		||||
    throw m[1];
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export { decodeFontData, encodeFontData, ttx, verifyTtxOutput };
 | 
			
		||||
							
								
								
									
										158
									
								
								test/font/jasmine-boot.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								test/font/jasmine-boot.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,158 @@
 | 
			
		||||
/* Copyright 2016 Mozilla Foundation
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
/*
 | 
			
		||||
 Copyright (c) 2008-2016 Pivotal Labs
 | 
			
		||||
 | 
			
		||||
 Permission is hereby granted, free of charge, to any person obtaining
 | 
			
		||||
 a copy of this software and associated documentation files (the
 | 
			
		||||
 "Software"), to deal in the Software without restriction, including
 | 
			
		||||
 without limitation the rights to use, copy, modify, merge, publish,
 | 
			
		||||
 distribute, sublicense, and/or sell copies of the Software, and to
 | 
			
		||||
 permit persons to whom the Software is furnished to do so, subject to
 | 
			
		||||
 the following conditions:
 | 
			
		||||
 | 
			
		||||
 The above copyright notice and this permission notice shall be
 | 
			
		||||
 included in all copies or substantial portions of the Software.
 | 
			
		||||
 | 
			
		||||
 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | 
			
		||||
 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | 
			
		||||
 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | 
			
		||||
 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 | 
			
		||||
 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 | 
			
		||||
 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 | 
			
		||||
 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | 
			
		||||
 */
 | 
			
		||||
/* globals jasmineRequire */
 | 
			
		||||
 | 
			
		||||
// Modified jasmine's boot.js file to load PDF.js libraries async.
 | 
			
		||||
 | 
			
		||||
"use strict";
 | 
			
		||||
 | 
			
		||||
import { TestReporter } from "../reporter.js";
 | 
			
		||||
 | 
			
		||||
async function initializePDFJS(callback) {
 | 
			
		||||
  await Promise.all(
 | 
			
		||||
    [
 | 
			
		||||
      "pdfjs-test/font/font_core_spec.js",
 | 
			
		||||
      "pdfjs-test/font/font_os2_spec.js",
 | 
			
		||||
      "pdfjs-test/font/font_post_spec.js",
 | 
			
		||||
      "pdfjs-test/font/font_fpgm_spec.js",
 | 
			
		||||
    ].map(moduleName => import(moduleName)) // eslint-disable-line no-unsanitized/method
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  callback();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
(function () {
 | 
			
		||||
  window.jasmine = jasmineRequire.core(jasmineRequire);
 | 
			
		||||
 | 
			
		||||
  jasmineRequire.html(jasmine);
 | 
			
		||||
 | 
			
		||||
  const env = jasmine.getEnv();
 | 
			
		||||
 | 
			
		||||
  const jasmineInterface = jasmineRequire.interface(jasmine, env);
 | 
			
		||||
  extend(window, jasmineInterface);
 | 
			
		||||
 | 
			
		||||
  // Runner Parameters
 | 
			
		||||
  const queryString = new jasmine.QueryString({
 | 
			
		||||
    getWindowLocation() {
 | 
			
		||||
      return window.location;
 | 
			
		||||
    },
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  const config = {
 | 
			
		||||
    failFast: queryString.getParam("failFast"),
 | 
			
		||||
    oneFailurePerSpec: queryString.getParam("oneFailurePerSpec"),
 | 
			
		||||
    hideDisabled: queryString.getParam("hideDisabled"),
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const random = queryString.getParam("random");
 | 
			
		||||
  if (random !== undefined && random !== "") {
 | 
			
		||||
    config.random = random;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const seed = queryString.getParam("seed");
 | 
			
		||||
  if (seed) {
 | 
			
		||||
    config.seed = seed;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Reporters
 | 
			
		||||
  const htmlReporter = new jasmine.HtmlReporter({
 | 
			
		||||
    env,
 | 
			
		||||
    navigateWithNewParam(key, value) {
 | 
			
		||||
      return queryString.navigateWithNewParam(key, value);
 | 
			
		||||
    },
 | 
			
		||||
    addToExistingQueryString(key, value) {
 | 
			
		||||
      return queryString.fullStringWithNewParam(key, value);
 | 
			
		||||
    },
 | 
			
		||||
    getContainer() {
 | 
			
		||||
      return document.body;
 | 
			
		||||
    },
 | 
			
		||||
    createElement() {
 | 
			
		||||
      return document.createElement(...arguments);
 | 
			
		||||
    },
 | 
			
		||||
    createTextNode() {
 | 
			
		||||
      return document.createTextNode(...arguments);
 | 
			
		||||
    },
 | 
			
		||||
    timer: new jasmine.Timer(),
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  env.addReporter(htmlReporter);
 | 
			
		||||
 | 
			
		||||
  if (queryString.getParam("browser")) {
 | 
			
		||||
    const testReporter = new TestReporter(queryString.getParam("browser"));
 | 
			
		||||
    env.addReporter(testReporter);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Filter which specs will be run by matching the start of the full name
 | 
			
		||||
  // against the `spec` query param.
 | 
			
		||||
  const specFilter = new jasmine.HtmlSpecFilter({
 | 
			
		||||
    filterString() {
 | 
			
		||||
      return queryString.getParam("spec");
 | 
			
		||||
    },
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  config.specFilter = function (spec) {
 | 
			
		||||
    return specFilter.matches(spec.getFullName());
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  env.configure(config);
 | 
			
		||||
 | 
			
		||||
  // Sets longer timeout.
 | 
			
		||||
  jasmine.DEFAULT_TIMEOUT_INTERVAL = 30000;
 | 
			
		||||
 | 
			
		||||
  function extend(destination, source) {
 | 
			
		||||
    for (const property in source) {
 | 
			
		||||
      destination[property] = source[property];
 | 
			
		||||
    }
 | 
			
		||||
    return destination;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function fontTestInit() {
 | 
			
		||||
    initializePDFJS(function () {
 | 
			
		||||
      htmlReporter.initialize();
 | 
			
		||||
      env.execute();
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if (
 | 
			
		||||
    document.readyState === "interactive" ||
 | 
			
		||||
    document.readyState === "complete"
 | 
			
		||||
  ) {
 | 
			
		||||
    fontTestInit();
 | 
			
		||||
  } else {
 | 
			
		||||
    document.addEventListener("DOMContentLoaded", fontTestInit, true);
 | 
			
		||||
  }
 | 
			
		||||
})();
 | 
			
		||||
							
								
								
									
										71
									
								
								test/font/ttxdriver.mjs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								test/font/ttxdriver.mjs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,71 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright 2014 Mozilla Foundation
 | 
			
		||||
 *
 | 
			
		||||
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
			
		||||
 * you may not use this file except in compliance with the License.
 | 
			
		||||
 * You may obtain a copy of the License at
 | 
			
		||||
 *
 | 
			
		||||
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
			
		||||
 *
 | 
			
		||||
 * Unless required by applicable law or agreed to in writing, software
 | 
			
		||||
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
			
		||||
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
			
		||||
 * See the License for the specific language governing permissions and
 | 
			
		||||
 * limitations under the License.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import fs from "fs";
 | 
			
		||||
import os from "os";
 | 
			
		||||
import path from "path";
 | 
			
		||||
import { spawn } from "child_process";
 | 
			
		||||
 | 
			
		||||
let ttxTaskId = Date.now();
 | 
			
		||||
 | 
			
		||||
function runTtx(fontPath) {
 | 
			
		||||
  return new Promise((resolve, reject) => {
 | 
			
		||||
    const ttx = spawn("ttx", [fontPath], { stdio: "ignore" });
 | 
			
		||||
    ttx.on("error", () => {
 | 
			
		||||
      reject(
 | 
			
		||||
        new Error(
 | 
			
		||||
          "Unable to execute `ttx`; make sure the `fonttools` dependency is installed"
 | 
			
		||||
        )
 | 
			
		||||
      );
 | 
			
		||||
    });
 | 
			
		||||
    ttx.on("close", () => {
 | 
			
		||||
      resolve();
 | 
			
		||||
    });
 | 
			
		||||
  });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
async function translateFont(content) {
 | 
			
		||||
  const buffer = Buffer.from(content, "base64");
 | 
			
		||||
  const taskId = (ttxTaskId++).toString();
 | 
			
		||||
  const fontPath = path.join(os.tmpdir(), `pdfjs-font-test-${taskId}.otf`);
 | 
			
		||||
  const resultPath = path.join(os.tmpdir(), `pdfjs-font-test-${taskId}.ttx`);
 | 
			
		||||
 | 
			
		||||
  // Write the font data to a temporary file on disk (because TTX only accepts
 | 
			
		||||
  // files as input).
 | 
			
		||||
  fs.writeFileSync(fontPath, buffer);
 | 
			
		||||
 | 
			
		||||
  // Run TTX on the temporary font file.
 | 
			
		||||
  let ttxError;
 | 
			
		||||
  try {
 | 
			
		||||
    await runTtx(fontPath);
 | 
			
		||||
  } catch (error) {
 | 
			
		||||
    ttxError = error;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Remove the temporary font/result files and report on the outcome.
 | 
			
		||||
  fs.unlinkSync(fontPath);
 | 
			
		||||
  if (ttxError) {
 | 
			
		||||
    throw ttxError;
 | 
			
		||||
  }
 | 
			
		||||
  if (!fs.existsSync(resultPath)) {
 | 
			
		||||
    throw new Error("TTX did not generate output");
 | 
			
		||||
  }
 | 
			
		||||
  const xml = fs.readFileSync(resultPath);
 | 
			
		||||
  fs.unlinkSync(resultPath);
 | 
			
		||||
  return xml;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export { translateFont };
 | 
			
		||||
		Reference in New Issue
	
	Block a user