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

This commit is contained in:
2025-10-03 22:20:19 +08:00
commit 44db9807a1
2172 changed files with 526822 additions and 0 deletions

View File

@@ -0,0 +1,43 @@
<!DOCTYPE html>
<!--
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.
-->
<html dir="ltr" mozdisallowselectionprint>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="google" content="notranslate">
<title>PDF.js page viewer using built components</title>
<style>
body {
background-color: #808080;
margin: 0;
padding: 0;
}
</style>
<link rel="stylesheet" href="../../node_modules/pdfjs-dist/web/pdf_viewer.css">
<script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script>
<script src="../../node_modules/pdfjs-dist/web/pdf_viewer.mjs" type="module"></script>
</head>
<body tabindex="1">
<div id="pageContainer" class="pdfViewer singlePageView"></div>
<script src="pageviewer.mjs" type="module"></script>
</body>
</html>

View File

@@ -0,0 +1,63 @@
/* 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.
*/
if (!pdfjsLib.getDocument || !pdfjsViewer.PDFPageView) {
// eslint-disable-next-line no-alert
alert("Please build the pdfjs-dist library using\n `gulp dist-install`");
}
// The workerSrc property shall be specified.
//
pdfjsLib.GlobalWorkerOptions.workerSrc =
"../../node_modules/pdfjs-dist/build/pdf.worker.mjs";
// Some PDFs need external cmaps.
//
const CMAP_URL = "../../node_modules/pdfjs-dist/cmaps/";
const CMAP_PACKED = true;
const DEFAULT_URL = "../../web/compressed.tracemonkey-pldi-09.pdf";
const PAGE_TO_VIEW = 1;
const SCALE = 1.0;
const ENABLE_XFA = true;
const container = document.getElementById("pageContainer");
const eventBus = new pdfjsViewer.EventBus();
// Loading document.
const loadingTask = pdfjsLib.getDocument({
url: DEFAULT_URL,
cMapUrl: CMAP_URL,
cMapPacked: CMAP_PACKED,
enableXfa: ENABLE_XFA,
});
const pdfDocument = await loadingTask.promise;
// Document loaded, retrieving the page.
const pdfPage = await pdfDocument.getPage(PAGE_TO_VIEW);
// Creating the page view with default parameters.
const pdfPageView = new pdfjsViewer.PDFPageView({
container,
id: PAGE_TO_VIEW,
scale: SCALE,
defaultViewport: pdfPage.getViewport({ scale: SCALE }),
eventBus,
});
// Associate the actual page with the view, and draw it.
pdfPageView.setPdfPage(pdfPage);
pdfPageView.draw();

View File

@@ -0,0 +1,51 @@
<!DOCTYPE html>
<!--
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.
-->
<html dir="ltr" mozdisallowselectionprint>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="google" content="notranslate">
<title>PDF.js viewer using built components</title>
<style>
body {
background-color: #808080;
margin: 0;
padding: 0;
}
#viewerContainer {
overflow: auto;
position: absolute;
width: 100%;
height: 100%;
}
</style>
<link rel="stylesheet" href="../../node_modules/pdfjs-dist/web/pdf_viewer.css">
<script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script>
<script src="../../node_modules/pdfjs-dist/web/pdf_viewer.mjs" type="module"></script>
</head>
<body tabindex="1">
<div id="viewerContainer">
<div id="viewer" class="pdfViewer"></div>
</div>
<script src="simpleviewer.mjs" type="module"></script>
</body>
</html>

View File

@@ -0,0 +1,97 @@
/* 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.
*/
if (!pdfjsLib.getDocument || !pdfjsViewer.PDFViewer) {
// eslint-disable-next-line no-alert
alert("Please build the pdfjs-dist library using\n `gulp dist-install`");
}
// The workerSrc property shall be specified.
//
pdfjsLib.GlobalWorkerOptions.workerSrc =
"../../node_modules/pdfjs-dist/build/pdf.worker.mjs";
// Some PDFs need external cmaps.
//
const CMAP_URL = "../../node_modules/pdfjs-dist/cmaps/";
const CMAP_PACKED = true;
const DEFAULT_URL = "../../web/compressed.tracemonkey-pldi-09.pdf";
// To test the AcroForm and/or scripting functionality, try e.g. this file:
// "../../test/pdfs/160F-2019.pdf"
const ENABLE_XFA = true;
const SEARCH_FOR = ""; // try "Mozilla";
const SANDBOX_BUNDLE_SRC = new URL(
"../../node_modules/pdfjs-dist/build/pdf.sandbox.mjs",
window.location
);
const container = document.getElementById("viewerContainer");
const eventBus = new pdfjsViewer.EventBus();
// (Optionally) enable hyperlinks within PDF files.
const pdfLinkService = new pdfjsViewer.PDFLinkService({
eventBus,
});
// (Optionally) enable find controller.
const pdfFindController = new pdfjsViewer.PDFFindController({
eventBus,
linkService: pdfLinkService,
});
// (Optionally) enable scripting support.
const pdfScriptingManager = new pdfjsViewer.PDFScriptingManager({
eventBus,
sandboxBundleSrc: SANDBOX_BUNDLE_SRC,
});
const pdfViewer = new pdfjsViewer.PDFViewer({
container,
eventBus,
linkService: pdfLinkService,
findController: pdfFindController,
scriptingManager: pdfScriptingManager,
});
pdfLinkService.setViewer(pdfViewer);
pdfScriptingManager.setViewer(pdfViewer);
eventBus.on("pagesinit", function () {
// We can use pdfViewer now, e.g. let's change default scale.
pdfViewer.currentScaleValue = "page-width";
// We can try searching for things.
if (SEARCH_FOR) {
eventBus.dispatch("find", { type: "", query: SEARCH_FOR });
}
});
// Loading document.
const loadingTask = pdfjsLib.getDocument({
url: DEFAULT_URL,
cMapUrl: CMAP_URL,
cMapPacked: CMAP_PACKED,
enableXfa: ENABLE_XFA,
});
const pdfDocument = await loadingTask.promise;
// Document loaded, specifying document for the viewer and
// the (optional) linkService.
pdfViewer.setDocument(pdfDocument);
pdfLinkService.setDocument(pdfDocument, null);

View File

@@ -0,0 +1,51 @@
<!DOCTYPE html>
<!--
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.
-->
<html dir="ltr" mozdisallowselectionprint>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="google" content="notranslate">
<title>PDF.js Single Page Viewer using built components</title>
<style>
body {
background-color: #808080;
margin: 0;
padding: 0;
}
#viewerContainer {
overflow: auto;
position: absolute;
width: 100%;
height: 100%;
}
</style>
<link rel="stylesheet" href="../../node_modules/pdfjs-dist/web/pdf_viewer.css">
<script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script>
<script src="../../node_modules/pdfjs-dist/web/pdf_viewer.mjs" type="module"></script>
</head>
<body tabindex="1">
<div id="viewerContainer">
<div id="viewer" class="pdfViewer"></div>
</div>
<script src="singlepageviewer.mjs" type="module"></script>
</body>
</html>

View File

@@ -0,0 +1,97 @@
/* 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.
*/
if (!pdfjsLib.getDocument || !pdfjsViewer.PDFSinglePageViewer) {
// eslint-disable-next-line no-alert
alert("Please build the pdfjs-dist library using\n `gulp dist-install`");
}
// The workerSrc property shall be specified.
//
pdfjsLib.GlobalWorkerOptions.workerSrc =
"../../node_modules/pdfjs-dist/build/pdf.worker.mjs";
// Some PDFs need external cmaps.
//
const CMAP_URL = "../../node_modules/pdfjs-dist/cmaps/";
const CMAP_PACKED = true;
const DEFAULT_URL = "../../web/compressed.tracemonkey-pldi-09.pdf";
// To test the AcroForm and/or scripting functionality, try e.g. this file:
// "../../test/pdfs/160F-2019.pdf"
const ENABLE_XFA = true;
const SEARCH_FOR = ""; // try "Mozilla";
const SANDBOX_BUNDLE_SRC = new URL(
"../../node_modules/pdfjs-dist/build/pdf.sandbox.mjs",
window.location
);
const container = document.getElementById("viewerContainer");
const eventBus = new pdfjsViewer.EventBus();
// (Optionally) enable hyperlinks within PDF files.
const pdfLinkService = new pdfjsViewer.PDFLinkService({
eventBus,
});
// (Optionally) enable find controller.
const pdfFindController = new pdfjsViewer.PDFFindController({
eventBus,
linkService: pdfLinkService,
});
// (Optionally) enable scripting support.
const pdfScriptingManager = new pdfjsViewer.PDFScriptingManager({
eventBus,
sandboxBundleSrc: SANDBOX_BUNDLE_SRC,
});
const pdfSinglePageViewer = new pdfjsViewer.PDFSinglePageViewer({
container,
eventBus,
linkService: pdfLinkService,
findController: pdfFindController,
scriptingManager: pdfScriptingManager,
});
pdfLinkService.setViewer(pdfSinglePageViewer);
pdfScriptingManager.setViewer(pdfSinglePageViewer);
eventBus.on("pagesinit", function () {
// We can use pdfSinglePageViewer now, e.g. let's change default scale.
pdfSinglePageViewer.currentScaleValue = "page-width";
// We can try searching for things.
if (SEARCH_FOR) {
eventBus.dispatch("find", { type: "", query: SEARCH_FOR });
}
});
// Loading document.
const loadingTask = pdfjsLib.getDocument({
url: DEFAULT_URL,
cMapUrl: CMAP_URL,
cMapPacked: CMAP_PACKED,
enableXfa: ENABLE_XFA,
});
const pdfDocument = await loadingTask.promise;
// Document loaded, specifying document for the viewer and
// the (optional) linkService.
pdfSinglePageViewer.setDocument(pdfDocument);
pdfLinkService.setDocument(pdfDocument, null);

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

View File

@@ -0,0 +1,40 @@
<!DOCTYPE html>
<!--
Copyright 2018 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.
-->
<html dir="ltr" mozdisallowselectionprint>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="google" content="notranslate">
<title>PDF.js standalone JpegImage parser</title>
<style>
body {
background-color: #808080;
margin: 0;
padding: 0;
}
</style>
<script src="../../node_modules/pdfjs-dist/image_decoders/pdf.image_decoders.mjs" type="module"></script>
</head>
<body tabindex="1">
<canvas id="jpegCanvas" width="0" height="0"></canvas>
<script src="jpeg_viewer.mjs" type="module"></script>
</body>
</html>

View File

@@ -0,0 +1,59 @@
/* Copyright 2018 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.
*/
if (!pdfjsImageDecoders.JpegImage) {
// eslint-disable-next-line no-alert
alert("Please build the pdfjs-dist library using `gulp dist-install`");
}
const JPEG_IMAGE = "fish.jpg";
const jpegCanvas = document.getElementById("jpegCanvas");
const jpegCtx = jpegCanvas.getContext("2d");
// Load the image data, and convert it to a Uint8Array.
//
const response = await fetch(JPEG_IMAGE);
if (!response.ok) {
throw new Error(response.statusText);
}
const typedArrayImage = new Uint8Array(await response.arrayBuffer());
// Parse the image data using `JpegImage`.
//
const jpegImage = new pdfjsImageDecoders.JpegImage();
jpegImage.parse(typedArrayImage);
const width = jpegImage.width,
height = jpegImage.height;
const jpegData = jpegImage.getData({
width,
height,
forceRGB: true,
});
// Render the JPEG image on a <canvas>.
//
const imageData = jpegCtx.createImageData(width, height);
const imageBytes = imageData.data;
for (let j = 0, k = 0, jj = width * height * 4; j < jj; ) {
imageBytes[j++] = jpegData[k++];
imageBytes[j++] = jpegData[k++];
imageBytes[j++] = jpegData[k++];
imageBytes[j++] = 255;
}
jpegCanvas.width = width;
jpegCanvas.height = height;
jpegCtx.putImageData(imageData, 0, 0);

View File

@@ -0,0 +1,76 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>'Hello, world!' example</title>
</head>
<body>
<h1>'Hello, world!' example</h1>
<canvas id="the-canvas" style="border: 1px solid black; direction: ltr;"></canvas>
<script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script>
<script id="script" type="module">
//
// If absolute URL from the remote server is provided, configure the CORS
// header on that server.
//
const url = './helloworld.pdf';
//
// The workerSrc property shall be specified.
//
pdfjsLib.GlobalWorkerOptions.workerSrc =
'../../node_modules/pdfjs-dist/build/pdf.worker.mjs';
//
// Asynchronous download PDF
//
const loadingTask = pdfjsLib.getDocument(url);
const pdf = await loadingTask.promise;
//
// Fetch the first page
//
const page = await pdf.getPage(1);
const scale = 1.5;
const viewport = page.getViewport({ scale });
// Support HiDPI-screens.
const outputScale = window.devicePixelRatio || 1;
//
// Prepare canvas using PDF page dimensions
//
const canvas = document.getElementById("the-canvas");
const context = canvas.getContext("2d");
canvas.width = Math.floor(viewport.width * outputScale);
canvas.height = Math.floor(viewport.height * outputScale);
canvas.style.width = Math.floor(viewport.width) + "px";
canvas.style.height = Math.floor(viewport.height) + "px";
const transform = outputScale !== 1
? [outputScale, 0, 0, outputScale, 0, 0]
: null;
//
// Render PDF page into canvas context
//
const renderContext = {
canvasContext: context,
transform,
viewport,
};
page.render(renderContext);
</script>
<hr>
<h2>JavaScript code:</h2>
<pre id="code"></pre>
<script>
document.getElementById('code').textContent =
document.getElementById('script').text;
</script>
</body>
</html>

View File

@@ -0,0 +1,68 @@
%PDF-1.7
1 0 obj % entry point
<<
/Type /Catalog
/Pages 2 0 R
>>
endobj
2 0 obj
<<
/Type /Pages
/MediaBox [ 0 0 200 200 ]
/Count 1
/Kids [ 3 0 R ]
>>
endobj
3 0 obj
<<
/Type /Page
/Parent 2 0 R
/Resources <<
/Font <<
/F1 4 0 R
>>
>>
/Contents 5 0 R
>>
endobj
4 0 obj
<<
/Type /Font
/Subtype /Type1
/BaseFont /Times-Roman
>>
endobj
5 0 obj % page content
<<
/Length 44
>>
stream
BT
70 50 TD
/F1 12 Tf
(Hello, world!) Tj
ET
endstream
endobj
xref
0 6
0000000000 65535 f
0000000010 00000 n
0000000079 00000 n
0000000173 00000 n
0000000301 00000 n
0000000380 00000 n
trailer
<<
/Size 6
/Root 1 0 R
>>
startxref
492
%%EOF

View File

@@ -0,0 +1,81 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>'Hello, world!' base64 example</title>
</head>
<body>
<h1>'Hello, world!' example</h1>
<canvas id="the-canvas" style="border: 1px solid black; direction: ltr;"></canvas>
<script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script>
<script id="script" type="module">
// atob() is used to convert base64 encoded PDF to binary-like data.
// (See also https://developer.mozilla.org/en-US/docs/Web/API/WindowBase64/
// Base64_encoding_and_decoding.)
var pdfData = atob(
'JVBERi0xLjcKCjEgMCBvYmogICUgZW50cnkgcG9pbnQKPDwKICAvVHlwZSAvQ2F0YWxvZwog' +
'IC9QYWdlcyAyIDAgUgo+PgplbmRvYmoKCjIgMCBvYmoKPDwKICAvVHlwZSAvUGFnZXMKICAv' +
'TWVkaWFCb3ggWyAwIDAgMjAwIDIwMCBdCiAgL0NvdW50IDEKICAvS2lkcyBbIDMgMCBSIF0K' +
'Pj4KZW5kb2JqCgozIDAgb2JqCjw8CiAgL1R5cGUgL1BhZ2UKICAvUGFyZW50IDIgMCBSCiAg' +
'L1Jlc291cmNlcyA8PAogICAgL0ZvbnQgPDwKICAgICAgL0YxIDQgMCBSIAogICAgPj4KICA+' +
'PgogIC9Db250ZW50cyA1IDAgUgo+PgplbmRvYmoKCjQgMCBvYmoKPDwKICAvVHlwZSAvRm9u' +
'dAogIC9TdWJ0eXBlIC9UeXBlMQogIC9CYXNlRm9udCAvVGltZXMtUm9tYW4KPj4KZW5kb2Jq' +
'Cgo1IDAgb2JqICAlIHBhZ2UgY29udGVudAo8PAogIC9MZW5ndGggNDQKPj4Kc3RyZWFtCkJU' +
'CjcwIDUwIFRECi9GMSAxMiBUZgooSGVsbG8sIHdvcmxkISkgVGoKRVQKZW5kc3RyZWFtCmVu' +
'ZG9iagoKeHJlZgowIDYKMDAwMDAwMDAwMCA2NTUzNSBmIAowMDAwMDAwMDEwIDAwMDAwIG4g' +
'CjAwMDAwMDAwNzkgMDAwMDAgbiAKMDAwMDAwMDE3MyAwMDAwMCBuIAowMDAwMDAwMzAxIDAw' +
'MDAwIG4gCjAwMDAwMDAzODAgMDAwMDAgbiAKdHJhaWxlcgo8PAogIC9TaXplIDYKICAvUm9v' +
'dCAxIDAgUgo+PgpzdGFydHhyZWYKNDkyCiUlRU9G');
//
// The workerSrc property shall be specified.
//
pdfjsLib.GlobalWorkerOptions.workerSrc =
'../../node_modules/pdfjs-dist/build/pdf.worker.mjs';
// Opening PDF by passing its binary data as a string. It is still preferable
// to use Uint8Array, but string or array-like structure will work too.
var loadingTask = pdfjsLib.getDocument({ data: pdfData, });
var pdf = await loadingTask.promise;
// Fetch the first page.
var page = await pdf.getPage(1);
var scale = 1.5;
var viewport = page.getViewport({ scale: scale, });
// Support HiDPI-screens.
var outputScale = window.devicePixelRatio || 1;
// Prepare canvas using PDF page dimensions.
var canvas = document.getElementById('the-canvas');
var context = canvas.getContext('2d');
canvas.width = Math.floor(viewport.width * outputScale);
canvas.height = Math.floor(viewport.height * outputScale);
canvas.style.width = Math.floor(viewport.width) + "px";
canvas.style.height = Math.floor(viewport.height) + "px";
var transform = outputScale !== 1
? [outputScale, 0, 0, outputScale, 0, 0]
: null;
// Render PDF page into canvas context.
var renderContext = {
canvasContext: context,
transform,
viewport,
};
page.render(renderContext);
</script>
<hr>
<h2>JavaScript code:</h2>
<pre id="code"></pre>
<script>
document.getElementById('code').textContent =
document.getElementById('script').text;
</script>
</body>
</html>

View File

@@ -0,0 +1,139 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Previous/Next example</title>
</head>
<body>
<h1>'Previous/Next' example</h1>
<div>
<button id="prev" type="button">Previous</button>
<button id="next" type="button">Next</button>
&nbsp; &nbsp;
<span>Page: <span id="page_num"></span> / <span id="page_count"></span></span>
</div>
<div>
<canvas id="the-canvas" style="border: 1px solid black; direction: ltr;"></canvas>
</div>
<script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script>
<script id="script" type="module">
//
// If absolute URL from the remote server is provided, configure the CORS
// header on that server.
//
var url = '../../web/compressed.tracemonkey-pldi-09.pdf';
//
// In cases when the pdf.worker.js is located at the different folder than the
// PDF.js's one, or the PDF.js is executed via eval(), the workerSrc property
// shall be specified.
//
pdfjsLib.GlobalWorkerOptions.workerSrc =
'../../node_modules/pdfjs-dist/build/pdf.worker.mjs';
var pdfDoc = null,
pageNum = 1,
pageRendering = false,
pageNumPending = null,
scale = 0.8,
canvas = document.getElementById('the-canvas'),
ctx = canvas.getContext('2d');
/**
* Get page info from document, resize canvas accordingly, and render page.
* @param num Page number.
*/
function renderPage(num) {
pageRendering = true;
// Using promise to fetch the page
pdfDoc.getPage(num).then(function(page) {
var viewport = page.getViewport({ scale: scale, });
// Support HiDPI-screens.
var outputScale = window.devicePixelRatio || 1;
canvas.width = Math.floor(viewport.width * outputScale);
canvas.height = Math.floor(viewport.height * outputScale);
canvas.style.width = Math.floor(viewport.width) + "px";
canvas.style.height = Math.floor(viewport.height) + "px";
var transform = outputScale !== 1
? [outputScale, 0, 0, outputScale, 0, 0]
: null;
// Render PDF page into canvas context
var renderContext = {
canvasContext: ctx,
transform: transform,
viewport: viewport,
};
var renderTask = page.render(renderContext);
// Wait for rendering to finish
renderTask.promise.then(function () {
pageRendering = false;
if (pageNumPending !== null) {
// New page rendering is pending
renderPage(pageNumPending);
pageNumPending = null;
}
});
});
// Update page counters
document.getElementById('page_num').textContent = num;
}
/**
* If another page rendering in progress, waits until the rendering is
* finished. Otherwise, executes rendering immediately.
*/
function queueRenderPage(num) {
if (pageRendering) {
pageNumPending = num;
} else {
renderPage(num);
}
}
/**
* Displays previous page.
*/
function onPrevPage() {
if (pageNum <= 1) {
return;
}
pageNum--;
queueRenderPage(pageNum);
}
document.getElementById('prev').addEventListener('click', onPrevPage);
/**
* Displays next page.
*/
function onNextPage() {
if (pageNum >= pdfDoc.numPages) {
return;
}
pageNum++;
queueRenderPage(pageNum);
}
document.getElementById('next').addEventListener('click', onNextPage);
/**
* Asynchronously downloads PDF.
*/
var loadingTask = pdfjsLib.getDocument(url);
pdfDoc = await loadingTask.promise;
document.getElementById('page_count').textContent = pdfDoc.numPages;
// Initial/first page rendering
renderPage(pageNum);
</script>
</body>
</html>

View File

@@ -0,0 +1,11 @@
## Overview
Example to demonstrate PDF.js library usage with a viewer optimized for mobile usage.
## Getting started
Build PDF.js using `gulp dist-install` and run `gulp server` to start a web server.
You can then work with the mobile viewer at
http://localhost:8888/examples/mobile-viewer/viewer.html.
Refer to `viewer.js` for the source code of the mobile viewer.

Binary file not shown.

After

Width:  |  Height:  |  Size: 169 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 295 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 295 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 560 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 395 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 640 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 564 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

View File

@@ -0,0 +1,242 @@
/* 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.
*/
* {
padding: 0;
margin: 0;
}
html {
height: 100%;
width: 100%;
overflow: hidden;
font-size: 10px;
}
header {
background-color: rgb(244 244 244 / 1);
}
header h1 {
border-bottom: 1px solid rgb(216 216 216 / 1);
color: rgb(133 133 133 / 1);
font-size: 23px;
font-style: italic;
font-weight: normal;
overflow: hidden;
padding: 10px;
text-align: center;
text-overflow: ellipsis;
white-space: nowrap;
}
body {
background: url(images/document_bg.png);
color: rgb(255 255 255 / 1);
font-family: sans-serif;
font-size: 10px;
height: 100%;
width: 100%;
overflow: hidden;
padding-bottom: 5rem;
}
section {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
font-size: 2rem;
}
footer {
background-image: url(images/toolbar_background.png);
height: 4rem;
position: absolute;
bottom: 0;
left: 0;
right: 0;
z-index: 1;
box-shadow: 0 -0.2rem 0.5rem rgb(50 50 50 / 0.75);
}
.toolbarButton {
display: block;
padding: 0;
margin: 0;
border-width: 0;
background-position: center center;
background-repeat: no-repeat;
background-color: rgb(0 0 0 / 0);
}
.toolbarButton.pageUp {
position: absolute;
width: 18%;
height: 100%;
left: 0;
background-image: url(images/icon_previous_page.png);
background-size: 2rem;
}
.toolbarButton.pageDown {
position: absolute;
width: 18%;
height: 100%;
left: 18%;
background-image: url(images/icon_next_page.png);
background-size: 2rem;
}
#pageNumber {
-moz-appearance: textfield; /* hides the spinner in moz */
position: absolute;
width: 28%;
height: 100%;
left: 36%;
text-align: center;
border: 0;
background-color: rgb(0 0 0 / 0);
font-size: 1.2rem;
color: rgb(255 255 255 / 1);
background-image:
url(images/div_line_left.png), url(images/div_line_right.png);
background-repeat: no-repeat;
background-position: left, right;
background-size: 0.2rem, 0.2rem;
}
.toolbarButton.zoomOut {
position: absolute;
width: 18%;
height: 100%;
left: 64%;
background-image: url(images/icon_zoom_out.png);
background-size: 2.4rem;
}
.toolbarButton.zoomIn {
position: absolute;
width: 18%;
height: 100%;
left: 82%;
background-image: url(images/icon_zoom_in.png);
background-size: 2.4rem;
}
.toolbarButton[disabled] {
opacity: 0.3;
}
.hidden {
display: none;
}
[hidden] {
display: none !important;
}
#viewerContainer {
position: absolute;
overflow: auto;
width: 100%;
inset: 5rem 0 4rem;
}
canvas {
margin: auto;
display: block;
}
.pdfViewer .page .loadingIcon {
width: 2.9rem;
height: 2.9rem;
background: url("images/spinner.png") no-repeat left top / 38rem;
border: medium none;
animation: 1s steps(10, end) 0s normal none infinite moveDefault;
display: block;
position: absolute;
top: calc((100% - 2.9rem) / 2);
left: calc((100% - 2.9rem) / 2);
}
@keyframes moveDefault {
from {
background-position: 0 top;
}
to {
background-position: -39rem top;
}
}
#loadingBar {
/* Define this variable here, and not in :root, to avoid reflowing the
entire viewer when updating progress (see issue 15958). */
--progressBar-percent: 0%;
position: relative;
height: 0.6rem;
background-color: rgb(51 51 51 / 1);
border-bottom: 1px solid rgb(51 51 51 / 1);
}
#loadingBar .progress {
position: absolute;
left: 0;
width: 100%;
transform: scaleX(var(--progressBar-percent));
transform-origin: 0 0;
height: 100%;
background-color: rgb(221 221 221 / 1);
overflow: hidden;
transition: transform 200ms;
}
@keyframes progressIndeterminate {
0% {
transform: translateX(0%);
}
50% {
transform: translateX(100%);
}
100% {
transform: translateX(100%);
}
}
#loadingBar.indeterminate .progress {
transform: none;
background-color: rgb(153 153 153 / 1);
transition: none;
}
#loadingBar.indeterminate .progress .glimmer {
position: absolute;
top: 0;
left: 0;
height: 100%;
width: 5rem;
background-image: linear-gradient(
to right,
rgb(153 153 153 / 1) 0%,
rgb(255 255 255 / 1) 50%,
rgb(153 153 153 / 1) 100%
);
background-size: 100% 100%;
background-repeat: no-repeat;
animation: progressIndeterminate 2s linear infinite;
}

View File

@@ -0,0 +1,57 @@
<!DOCTYPE html>
<!--
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.
-->
<html dir="ltr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<title>PDF.js viewer</title>
<link rel="stylesheet" href="../../node_modules/pdfjs-dist/web/pdf_viewer.css">
<link rel="stylesheet" type="text/css" href="viewer.css">
<script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script>
<script src="../../node_modules/pdfjs-dist/web/pdf_viewer.mjs" type="module"></script>
</head>
<body>
<header>
<h1 id="title"></h1>
</header>
<div id="viewerContainer">
<div id="viewer" class="pdfViewer"></div>
</div>
<div id="loadingBar">
<div class="progress"></div>
<div class="glimmer"></div>
</div>
<footer>
<button class="toolbarButton pageUp" title="Previous Page" id="previous" type="button"></button>
<button class="toolbarButton pageDown" title="Next Page" id="next" type="button"></button>
<input type="number" id="pageNumber" class="toolbarField pageNumber" value="1" size="4" min="1">
<button class="toolbarButton zoomOut" title="Zoom Out" id="zoomOut" type="button"></button>
<button class="toolbarButton zoomIn" title="Zoom In" id="zoomIn" type="button"></button>
</footer>
<script src="viewer.mjs" type="module"></script>
</body>
</html>

View File

@@ -0,0 +1,371 @@
/* 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.
*/
if (!pdfjsLib.getDocument || !pdfjsViewer.PDFViewer) {
// eslint-disable-next-line no-alert
alert("Please build the pdfjs-dist library using\n `gulp dist-install`");
}
const MAX_CANVAS_PIXELS = 0; // CSS-only zooming.
const TEXT_LAYER_MODE = 0; // DISABLE
const MAX_IMAGE_SIZE = 1024 * 1024;
const CMAP_URL = "../../node_modules/pdfjs-dist/cmaps/";
const CMAP_PACKED = true;
pdfjsLib.GlobalWorkerOptions.workerSrc =
"../../node_modules/pdfjs-dist/build/pdf.worker.mjs";
const DEFAULT_URL = "../../web/compressed.tracemonkey-pldi-09.pdf";
const DEFAULT_SCALE_DELTA = 1.1;
const MIN_SCALE = 0.25;
const MAX_SCALE = 10.0;
const DEFAULT_SCALE_VALUE = "auto";
const PDFViewerApplication = {
pdfLoadingTask: null,
pdfDocument: null,
pdfViewer: null,
pdfHistory: null,
pdfLinkService: null,
eventBus: null,
/**
* Opens PDF document specified by URL.
* @returns {Promise} - Returns the promise, which is resolved when document
* is opened.
*/
open(params) {
if (this.pdfLoadingTask) {
// We need to destroy already opened document
return this.close().then(
function () {
// ... and repeat the open() call.
return this.open(params);
}.bind(this)
);
}
const url = params.url;
const self = this;
this.setTitleUsingUrl(url);
// Loading document.
const loadingTask = pdfjsLib.getDocument({
url,
maxImageSize: MAX_IMAGE_SIZE,
cMapUrl: CMAP_URL,
cMapPacked: CMAP_PACKED,
});
this.pdfLoadingTask = loadingTask;
loadingTask.onProgress = function (progressData) {
self.progress(progressData.loaded / progressData.total);
};
return loadingTask.promise.then(
function (pdfDocument) {
// Document loaded, specifying document for the viewer.
self.pdfDocument = pdfDocument;
self.pdfViewer.setDocument(pdfDocument);
self.pdfLinkService.setDocument(pdfDocument);
self.pdfHistory.initialize({
fingerprint: pdfDocument.fingerprints[0],
});
self.loadingBar.hide();
self.setTitleUsingMetadata(pdfDocument);
},
function (reason) {
let key = "pdfjs-loading-error";
if (reason instanceof pdfjsLib.InvalidPDFException) {
key = "pdfjs-invalid-file-error";
} else if (reason instanceof pdfjsLib.ResponseException) {
key = reason.missing
? "pdfjs-missing-file-error"
: "pdfjs-unexpected-response-error";
}
self.l10n.get(key).then(msg => {
self.error(msg, { message: reason?.message });
});
self.loadingBar.hide();
}
);
},
/**
* Closes opened PDF document.
* @returns {Promise} - Returns the promise, which is resolved when all
* destruction is completed.
*/
close() {
if (!this.pdfLoadingTask) {
return Promise.resolve();
}
const promise = this.pdfLoadingTask.destroy();
this.pdfLoadingTask = null;
if (this.pdfDocument) {
this.pdfDocument = null;
this.pdfViewer.setDocument(null);
this.pdfLinkService.setDocument(null, null);
if (this.pdfHistory) {
this.pdfHistory.reset();
}
}
return promise;
},
get loadingBar() {
const bar = document.getElementById("loadingBar");
return pdfjsLib.shadow(
this,
"loadingBar",
new pdfjsViewer.ProgressBar(bar)
);
},
setTitleUsingUrl: function pdfViewSetTitleUsingUrl(url) {
this.url = url;
let title = pdfjsLib.getFilenameFromUrl(url) || url;
try {
title = decodeURIComponent(title);
} catch {
// decodeURIComponent may throw URIError,
// fall back to using the unprocessed url in that case
}
this.setTitle(title);
},
setTitleUsingMetadata(pdfDocument) {
const self = this;
pdfDocument.getMetadata().then(function (data) {
const info = data.info,
metadata = data.metadata;
self.documentInfo = info;
self.metadata = metadata;
// Provides some basic debug information
console.log(
"PDF " +
pdfDocument.fingerprints[0] +
" [" +
info.PDFFormatVersion +
" " +
(info.Producer || "-").trim() +
" / " +
(info.Creator || "-").trim() +
"]" +
" (PDF.js: " +
(pdfjsLib.version || "-") +
")"
);
let pdfTitle;
if (metadata && metadata.has("dc:title")) {
const title = metadata.get("dc:title");
// Ghostscript sometimes returns 'Untitled', so prevent setting the
// title to 'Untitled.
if (title !== "Untitled") {
pdfTitle = title;
}
}
if (!pdfTitle && info && info.Title) {
pdfTitle = info.Title;
}
if (pdfTitle) {
self.setTitle(pdfTitle + " - " + document.title);
}
});
},
setTitle: function pdfViewSetTitle(title) {
document.title = title;
document.getElementById("title").textContent = title;
},
error: function pdfViewError(message, moreInfo) {
const moreInfoText = [
`PDF.js v${pdfjsLib.version || "?"} (build: ${pdfjsLib.build || "?"})`,
];
if (moreInfo) {
moreInfoText.push(`Message: ${moreInfo.message}`);
if (moreInfo.stack) {
moreInfoText.push(`Stack: ${moreInfo.stack}`);
} else {
if (moreInfo.filename) {
moreInfoText.push(`File: ${moreInfo.filename}`);
}
if (moreInfo.lineNumber) {
moreInfoText.push(`Line: ${moreInfo.lineNumber}`);
}
}
}
console.error(`${message}\n\n${moreInfoText.join("\n")}`);
},
progress: function pdfViewProgress(level) {
const percent = Math.round(level * 100);
// Updating the bar if value increases.
if (percent > this.loadingBar.percent || isNaN(percent)) {
this.loadingBar.percent = percent;
}
},
get pagesCount() {
return this.pdfDocument.numPages;
},
get page() {
return this.pdfViewer.currentPageNumber;
},
set page(val) {
this.pdfViewer.currentPageNumber = val;
},
zoomIn: function pdfViewZoomIn(ticks) {
let newScale = this.pdfViewer.currentScale;
do {
newScale = (newScale * DEFAULT_SCALE_DELTA).toFixed(2);
newScale = Math.ceil(newScale * 10) / 10;
newScale = Math.min(MAX_SCALE, newScale);
} while (--ticks && newScale < MAX_SCALE);
this.pdfViewer.currentScaleValue = newScale;
},
zoomOut: function pdfViewZoomOut(ticks) {
let newScale = this.pdfViewer.currentScale;
do {
newScale = (newScale / DEFAULT_SCALE_DELTA).toFixed(2);
newScale = Math.floor(newScale * 10) / 10;
newScale = Math.max(MIN_SCALE, newScale);
} while (--ticks && newScale > MIN_SCALE);
this.pdfViewer.currentScaleValue = newScale;
},
initUI: function pdfViewInitUI() {
const eventBus = new pdfjsViewer.EventBus();
this.eventBus = eventBus;
const linkService = new pdfjsViewer.PDFLinkService({
eventBus,
});
this.pdfLinkService = linkService;
this.l10n = new pdfjsViewer.GenericL10n();
const container = document.getElementById("viewerContainer");
const pdfViewer = new pdfjsViewer.PDFViewer({
container,
eventBus,
linkService,
l10n: this.l10n,
maxCanvasPixels: MAX_CANVAS_PIXELS,
textLayerMode: TEXT_LAYER_MODE,
});
this.pdfViewer = pdfViewer;
linkService.setViewer(pdfViewer);
this.pdfHistory = new pdfjsViewer.PDFHistory({
eventBus,
linkService,
});
linkService.setHistory(this.pdfHistory);
document.getElementById("previous").addEventListener("click", function () {
PDFViewerApplication.page--;
});
document.getElementById("next").addEventListener("click", function () {
PDFViewerApplication.page++;
});
document.getElementById("zoomIn").addEventListener("click", function () {
PDFViewerApplication.zoomIn();
});
document.getElementById("zoomOut").addEventListener("click", function () {
PDFViewerApplication.zoomOut();
});
document
.getElementById("pageNumber")
.addEventListener("click", function () {
this.select();
});
document
.getElementById("pageNumber")
.addEventListener("change", function () {
PDFViewerApplication.page = this.value | 0;
// Ensure that the page number input displays the correct value,
// even if the value entered by the user was invalid
// (e.g. a floating point number).
if (this.value !== PDFViewerApplication.page.toString()) {
this.value = PDFViewerApplication.page;
}
});
eventBus.on("pagesinit", function () {
// We can use pdfViewer now, e.g. let's change default scale.
pdfViewer.currentScaleValue = DEFAULT_SCALE_VALUE;
});
eventBus.on(
"pagechanging",
function (evt) {
const page = evt.pageNumber;
const numPages = PDFViewerApplication.pagesCount;
document.getElementById("pageNumber").value = page;
document.getElementById("previous").disabled = page <= 1;
document.getElementById("next").disabled = page >= numPages;
},
true
);
},
};
window.PDFViewerApplication = PDFViewerApplication;
document.addEventListener(
"DOMContentLoaded",
function () {
PDFViewerApplication.initUI();
},
true
);
// The offsetParent is not set until the PDF.js iframe or object is visible;
// waiting for first animation.
const animationStarted = new Promise(function (resolve) {
window.requestAnimationFrame(resolve);
});
// We need to delay opening until all HTML is loaded.
animationStarted.then(function () {
PDFViewerApplication.open({
url: DEFAULT_URL,
});
});

76
examples/node/getinfo.mjs Normal file
View File

@@ -0,0 +1,76 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
//
// Basic node example that prints document metadata and text content.
//
// Run `gulp dist-install` to generate 'pdfjs-dist' npm package files.
import { getDocument } from "pdfjs-dist/legacy/build/pdf.mjs";
// Loading file from file system into typed array
const pdfPath =
process.argv[2] || "../../web/compressed.tracemonkey-pldi-09.pdf";
// Will be using promises to load document, pages and misc data instead of
// callback.
const loadingTask = getDocument(pdfPath);
loadingTask.promise
.then(function (doc) {
const numPages = doc.numPages;
console.log("# Document Loaded");
console.log("Number of Pages: " + numPages);
console.log();
let lastPromise; // will be used to chain promises
lastPromise = doc.getMetadata().then(function (data) {
console.log("# Metadata Is Loaded");
console.log("## Info");
console.log(JSON.stringify(data.info, null, 2));
console.log();
if (data.metadata) {
console.log("## Metadata");
console.log(JSON.stringify(data.metadata.getAll(), null, 2));
console.log();
}
});
const loadPage = function (pageNum) {
return doc.getPage(pageNum).then(function (page) {
console.log("# Page " + pageNum);
const viewport = page.getViewport({ scale: 1.0 });
console.log("Size: " + viewport.width + "x" + viewport.height);
console.log();
return page
.getTextContent()
.then(function (content) {
// Content contains lots of information about the text layout and
// styles, but we need only strings at the moment
const strings = content.items.map(function (item) {
return item.str;
});
console.log("## Text Content");
console.log(strings.join(" "));
// Release page resources.
page.cleanup();
})
.then(function () {
console.log();
});
});
};
// Loading of the first page will wait on metadata and subsequent loadings
// will wait on the previous pages.
for (let i = 1; i <= numPages; i++) {
lastPromise = lastPromise.then(loadPage.bind(null, i));
}
return lastPromise;
})
.then(
function () {
console.log("# End of Document");
},
function (err) {
console.error("Error: " + err);
}
);

View File

@@ -0,0 +1,15 @@
## Overview
Example to demonstrate converting a PDF file to a PNG image using the PDF.js library.
## Getting started
Install the dependencies and build the PDF.js library:
$ npm install
$ gulp dist-install
Run the example to convert the first page of a PDF file to a PNG image:
$ cd examples/node/pdf2png
$ node pdf2png.mjs

View File

@@ -0,0 +1,72 @@
/* Copyright 2017 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 { getDocument } from "pdfjs-dist/legacy/build/pdf.mjs";
// Some PDFs need external cmaps.
const CMAP_URL = "../../../node_modules/pdfjs-dist/cmaps/";
const CMAP_PACKED = true;
// Where the standard fonts are located.
const STANDARD_FONT_DATA_URL =
"../../../node_modules/pdfjs-dist/standard_fonts/";
// Loading file from file system into typed array.
const pdfPath =
process.argv[2] || "../../../web/compressed.tracemonkey-pldi-09.pdf";
const data = new Uint8Array(fs.readFileSync(pdfPath));
// Load the PDF file.
const loadingTask = getDocument({
data,
cMapUrl: CMAP_URL,
cMapPacked: CMAP_PACKED,
standardFontDataUrl: STANDARD_FONT_DATA_URL,
});
try {
const pdfDocument = await loadingTask.promise;
console.log("# PDF document loaded.");
// Get the first page.
const page = await pdfDocument.getPage(1);
// Render the page on a Node canvas with 100% scale.
const canvasFactory = pdfDocument.canvasFactory;
const viewport = page.getViewport({ scale: 1.0 });
const canvasAndContext = canvasFactory.create(
viewport.width,
viewport.height
);
const renderContext = {
canvasContext: canvasAndContext.context,
viewport,
};
const renderTask = page.render(renderContext);
await renderTask.promise;
// Convert the canvas to an image buffer.
const image = canvasAndContext.canvas.toBuffer("image/png");
fs.writeFile("output.png", image, function (error) {
if (error) {
console.error("Error: " + error);
} else {
console.log("Finished converting first page of PDF file to a PNG image.");
}
});
// Release page resources.
page.cleanup();
} catch (reason) {
console.log(reason);
}

View File

@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Text-only PDF.js example</title>
<script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script>
<script src="pdf2svg.mjs" type="module"></script>
</head>
<body>
<p>Text-only PDF.js example</p>
<div id="pageContainer" style="display: inline-block; border: solid 1px black;">
</div>
</body>
</html>

View File

@@ -0,0 +1,72 @@
/* 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.
*/
const PDF_PATH = "../../web/compressed.tracemonkey-pldi-09.pdf";
const PAGE_NUMBER = 1;
const PAGE_SCALE = 1.5;
const SVG_NS = "http://www.w3.org/2000/svg";
pdfjsLib.GlobalWorkerOptions.workerSrc =
"../../node_modules/pdfjs-dist/build/pdf.worker.mjs";
function buildSVG(viewport, textContent) {
// Building SVG with size of the viewport (for simplicity)
const svg = document.createElementNS(SVG_NS, "svg:svg");
svg.setAttribute("width", viewport.width + "px");
svg.setAttribute("height", viewport.height + "px");
// items are transformed to have 1px font size
svg.setAttribute("font-size", 1);
// processing all items
textContent.items.forEach(function (textItem) {
// we have to take in account viewport transform, which includes scale,
// rotation and Y-axis flip, and not forgetting to flip text.
const tx = pdfjsLib.Util.transform(
pdfjsLib.Util.transform(viewport.transform, textItem.transform),
[1, 0, 0, -1, 0, 0]
);
const style = textContent.styles[textItem.fontName];
// adding text element
const text = document.createElementNS(SVG_NS, "svg:text");
text.setAttribute("transform", "matrix(" + tx.join(" ") + ")");
text.setAttribute("font-family", style.fontFamily);
text.textContent = textItem.str;
svg.append(text);
});
return svg;
}
async function pageLoaded() {
// Loading document and page text content
const loadingTask = pdfjsLib.getDocument({ url: PDF_PATH });
const pdfDocument = await loadingTask.promise;
const page = await pdfDocument.getPage(PAGE_NUMBER);
const viewport = page.getViewport({ scale: PAGE_SCALE });
const textContent = await page.getTextContent();
// building SVG and adding that to the DOM
const svg = buildSVG(viewport, textContent);
document.getElementById("pageContainer").append(svg);
// Release page resources.
page.cleanup();
}
document.addEventListener("DOMContentLoaded", function () {
if (typeof pdfjsLib === "undefined") {
// eslint-disable-next-line no-alert
alert("Please build the pdfjs-dist library using\n `gulp dist-install`");
return;
}
pageLoaded();
});

1
examples/webpack/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
node_modules/

View File

@@ -0,0 +1,33 @@
## Overview
Example to demonstrate PDF.js library usage with Webpack.
## Getting started
Install the example dependencies and build the project:
$ gulp dist-install
$ cd examples/webpack
$ npm install
$ ./node_modules/webpack/bin/webpack.js
You can observe the build results by running `gulp server` and navigating to
http://localhost:8888/examples/webpack/index.html.
Refer to the `main.js` and `webpack.config.js` files for the source code.
Note that PDF.js packaging requires packaging of the main application and
the worker code, and the `workerSrc` path shall be set to the latter file.
### Minification
If you are configuring Webpack to output a minified build, please note that you
*must* configure the minifier to keep original class/function names intact;
otherwise the build is not guaranteed to work correctly.
## Worker loading
If you are getting the `Setting up fake worker` warning, make sure you are
importing `pdfjs-dist/webpack.mjs` which is the zero-configuration method for
Webpack users. Installing `worker-loader` is no longer necessary.
import * as pdfjsLib from 'pdfjs-dist/webpack.mjs';

View File

@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>webpack example</title>
<script src="../../build/webpack/main.bundle.js"></script>
</head>
<body>
<canvas id="theCanvas"></canvas>
</body>
</html>

29
examples/webpack/main.mjs Normal file
View File

@@ -0,0 +1,29 @@
// Any copyright is dedicated to the Public Domain.
// http://creativecommons.org/licenses/publicdomain/
// Hello world example for webpack.
import * as pdfjsLib from "pdfjs-dist";
const pdfPath = "../learning/helloworld.pdf";
// Setting worker path to worker bundle.
pdfjsLib.GlobalWorkerOptions.workerSrc =
"../../build/webpack/pdf.worker.bundle.js";
// Loading a document.
const loadingTask = pdfjsLib.getDocument(pdfPath);
const pdfDocument = await loadingTask.promise;
// Request a first page
const pdfPage = await pdfDocument.getPage(1);
// Display page on the existing canvas with 100% scale.
const viewport = pdfPage.getViewport({ scale: 1.0 });
const canvas = document.getElementById("theCanvas");
canvas.width = viewport.width;
canvas.height = viewport.height;
const ctx = canvas.getContext("2d");
const renderTask = pdfPage.render({
canvasContext: ctx,
viewport,
});
await renderTask.promise;

View File

@@ -0,0 +1,12 @@
{
"name": "webpack-pdf.js-example",
"version": "0.2.0",
"scripts": {
"build": "webpack"
},
"devDependencies": {
"webpack": "^5.89.0",
"webpack-cli": "^5.1.4",
"pdfjs-dist": "../../node_modules/pdfjs-dist"
}
}

View File

@@ -0,0 +1,18 @@
/* eslint-disable import/no-commonjs */
const webpack = require("webpack"); // eslint-disable-line no-unused-vars
const path = require("path");
module.exports = {
context: __dirname,
entry: {
main: "./main.mjs",
"pdf.worker": "pdfjs-dist/build/pdf.worker.mjs",
},
mode: "none",
output: {
path: path.join(__dirname, "../../build/webpack"),
publicPath: "../../build/webpack/",
filename: "[name].bundle.js",
},
};