Compare commits

..

No commits in common. "master" and "v1.0.1040" have entirely different histories.

2096 changed files with 97247 additions and 460849 deletions

View File

@ -1,20 +0,0 @@
root = true
[*.{js,jsm,mjs,json,html,css,pdf.link}]
charset = utf-8
end_of_line = lf
indent_size = 2
indent_style = space
insert_final_newline = true
max_line_length = 80
trim_trailing_whitespace = true
[*.{json,pdf.link}]
max_line_length = off
[*.md]
max_line_length = off
trim_trailing_whitespace = false
[COMMIT_EDITMSG]
max_line_length = off

View File

@ -1,12 +0,0 @@
build/
l10n/
docs/
node_modules/
external/bcmaps/
external/builder/fixtures/
external/builder/fixtures_esprima/
external/quickjs/
test/tmp/
test/pdfs/
web/locale/
*~/

267
.eslintrc
View File

@ -1,267 +0,0 @@
{
"parserOptions": {
"ecmaVersion": 2022,
"sourceType": "module",
},
"plugins": [
"import",
"json",
"mozilla",
"no-unsanitized",
"sort-exports",
"unicorn",
],
"extends": [
"plugin:json/recommended",
"plugin:prettier/recommended"
],
"env": {
"browser": true,
"es2022": true,
"worker": true,
},
"globals": {
"PDFJSDev": "readonly",
"__non_webpack_import__": "readonly",
},
"rules": {
// Plugins
"import/export": "error",
"import/exports-last": "error",
"import/extensions": ["error", "always", { "ignorePackages": true, }],
"import/first": "error",
"import/named": "error",
"import/no-cycle": "error",
"import/no-empty-named-blocks": "error",
"import/no-commonjs": "error",
"import/no-mutable-exports": "error",
"import/no-self-import": "error",
"import/no-unresolved": ["error", {
"ignore": ["display", "pdfjs", "pdfjs-lib", "pdfjs-web", "web", "fluent-bundle", "fluent-dom"],
}],
"mozilla/avoid-removeChild": "error",
"mozilla/use-includes-instead-of-indexOf": "error",
"no-unsanitized/method": "error",
"no-unsanitized/property": "error",
"sort-exports/sort-exports": ["error", {
"ignoreCase": true,
}],
"unicorn/no-abusive-eslint-disable": "error",
"unicorn/no-array-push-push": "error",
"unicorn/no-instanceof-array": "error",
"unicorn/no-invalid-remove-event-listener": "error",
"unicorn/no-new-buffer": "error",
"unicorn/no-typeof-undefined": ["error", {
"checkGlobalVariables": false,
}],
"unicorn/no-useless-promise-resolve-reject": "error",
"unicorn/no-useless-spread": "error",
"unicorn/prefer-array-find": "error",
"unicorn/prefer-array-flat": "error",
"unicorn/prefer-array-flat-map": "error",
"unicorn/prefer-array-index-of": "error",
"unicorn/prefer-array-some": "error",
"unicorn/prefer-at": "error",
"unicorn/prefer-date-now": "error",
"unicorn/prefer-dom-node-append": "error",
"unicorn/prefer-dom-node-remove": "error",
"unicorn/prefer-logical-operator-over-ternary": "error",
"unicorn/prefer-modern-dom-apis": "error",
"unicorn/prefer-modern-math-apis": "error",
"unicorn/prefer-negative-index": "error",
"unicorn/prefer-optional-catch-binding": "error",
"unicorn/prefer-regexp-test": "error",
"unicorn/prefer-string-replace-all": "error",
"unicorn/prefer-string-starts-ends-with": "error",
"unicorn/prefer-ternary": ["error", "only-single-line"],
// Possible errors
"for-direction": "error",
"getter-return": "error",
"no-async-promise-executor": "error",
"no-cond-assign": ["error", "except-parens"],
"no-constant-condition": ["error", { "checkLoops": false, }],
"no-debugger": "error",
"no-dupe-args": "error",
"no-dupe-else-if": "error",
"no-dupe-keys": "error",
"no-duplicate-case": "error",
"no-empty": ["error", { "allowEmptyCatch": true, }],
"no-empty-character-class": "error",
"no-ex-assign": "error",
"no-extra-boolean-cast": "error",
"no-func-assign": "error",
"no-inner-declarations": ["error", "functions"],
"no-invalid-regexp": "error",
"no-irregular-whitespace": "error",
"no-loss-of-precision": "error",
"no-obj-calls": "error",
"no-promise-executor-return": "error",
"no-regex-spaces": "error",
"no-setter-return": "error",
"no-sparse-arrays": "error",
"no-template-curly-in-string": "error",
"no-unexpected-multiline": "error",
"no-unreachable": "error",
"no-unsafe-finally": "error",
"no-unsafe-negation": "error",
"no-unsafe-optional-chaining": ["error", { "disallowArithmeticOperators": true }],
"no-unused-private-class-members": "error",
"use-isnan": ["error", { "enforceForIndexOf": true, }],
"valid-typeof": ["error", { "requireStringLiterals": true, }],
// Best Practices
"accessor-pairs": ["error", {
"setWithoutGet": true,
"enforceForClassMembers": true,
}],
"consistent-return": "error",
"curly": ["error", "all"],
"default-case-last": "error",
"dot-notation": "error",
"eqeqeq": ["error", "always"],
"grouped-accessor-pairs": ["error", "getBeforeSet"],
"no-alert": "error",
"no-caller": "error",
"no-else-return": "error",
"no-empty-pattern": "error",
"no-eval": "error",
"no-extend-native": "error",
"no-extra-bind": "error",
"no-extra-label": "error",
"no-fallthrough": "error",
"no-floating-decimal": "error",
"no-global-assign": "error",
"no-implied-eval": "error",
"no-iterator": "error",
"no-lone-blocks": "error",
"no-lonely-if": "error",
"no-multi-str": "error",
"no-new": "error",
"no-new-func": "error",
"no-new-symbol": "error",
"no-new-wrappers": "error",
"no-octal-escape": "error",
"no-octal": "error",
"no-redeclare": "error",
"no-return-await": "error",
"no-self-assign": "error",
"no-self-compare": "error",
"no-throw-literal": "error",
"no-unused-expressions": "error",
"no-unused-labels": "error",
"no-useless-call": "error",
"no-useless-catch": "error",
"no-useless-concat": "error",
"no-useless-escape": "error",
"no-useless-return": "error",
"prefer-promise-reject-errors": "error",
"prefer-spread": "error",
"wrap-iife": ["error", "any"],
"yoda": ["error", "never", {
"exceptRange": true,
}],
// Strict Mode
"strict": ["off", "global"],
// Variables
"no-delete-var": "error",
"no-label-var": "error",
"no-shadow": "error",
"no-shadow-restricted-names": "error",
"no-undef-init": "error",
"no-undef": ["error", { "typeof": true, }],
"no-unused-vars": ["error", {
"vars": "all",
"args": "none",
}],
"no-use-before-define": ["error", {
"functions": false,
"classes": false,
"variables": false,
}],
// Stylistic Issues
"lines-between-class-members": ["error", "always"],
"max-len": ["error", {
"code": 1000,
"comments": 80,
"ignoreUrls": true
}],
"new-cap": ["error", { "newIsCap": true, "capIsNew": false, }],
"no-array-constructor": "error",
"no-multiple-empty-lines": ["error", { "max": 1, "maxEOF": 0, "maxBOF": 1, }],
"no-nested-ternary": "error",
"no-new-object": "error",
"no-restricted-syntax": ["error",
{
"selector": "BinaryExpression[operator='instanceof'][right.name='Object']",
"message": "Use `typeof` rather than `instanceof Object`.",
},
{
"selector": "CallExpression[callee.name='assert'][arguments.length!=2]",
"message": "`assert()` must always be invoked with two arguments.",
},
{
"selector": "CallExpression[callee.name='isCmd'][arguments.length<2]",
"message": "Use `instanceof Cmd` rather than `isCmd()` with one argument.",
},
{
"selector": "CallExpression[callee.name='isDict'][arguments.length<2]",
"message": "Use `instanceof Dict` rather than `isDict()` with one argument.",
},
{
"selector": "CallExpression[callee.name='isName'][arguments.length<2]",
"message": "Use `instanceof Name` rather than `isName()` with one argument.",
},
{
"selector": "NewExpression[callee.name='Cmd']",
"message": "Use `Cmd.get()` rather than `new Cmd()`.",
},
{
"selector": "NewExpression[callee.name='Name']",
"message": "Use `Name.get()` rather than `new Name()`.",
},
{
"selector": "NewExpression[callee.name='Ref']",
"message": "Use `Ref.get()` rather than `new Ref()`.",
},
],
"no-unneeded-ternary": "error",
"operator-assignment": "error",
"prefer-exponentiation-operator": "error",
"spaced-comment": ["error", "always", {
"block": {
"balanced": true,
}
}],
// ECMAScript 6
"arrow-body-style": ["error", "as-needed"],
"constructor-super": "error",
"no-class-assign": "error",
"no-const-assign": "error",
"no-dupe-class-members": "error",
"no-duplicate-imports": "error",
"no-this-before-super": "error",
"no-useless-computed-key": "error",
"no-useless-constructor": "error",
"no-useless-rename": "error",
"no-var": "error",
"object-shorthand": ["error", "always", {
"avoidQuotes": true,
}],
"prefer-const": "error",
"require-yield": "error",
"sort-imports": ["error", {
"ignoreCase": true,
}],
"template-curly-spacing": ["error", "never"],
},
}

View File

@ -1,6 +0,0 @@
# Auto-format `.js` files with ESLint/Prettier
de36b2aabab2b7fd647d9591f959c4540129541d
# Auto-format `.css` files with Stylelint/Prettier
8aa2718d225ad701a5b8a2788b42d221f1e4327d
# Auto-format `.json` files with Prettier
29de9bdce6c9785574994fda0e51533d796a9bb4

7
.gitattributes vendored
View File

@ -4,7 +4,7 @@
*.css text eol=lf
*.html text eol=lf
*.md text eol=lf
*.ftl text eol=lf
*.properties text eol=lf
*.yml text eol=lf
*.json text eol=lf
*.config text eol=lf
@ -16,8 +16,3 @@
# PDF files shall not modify CRLF line endings
*.pdf -crlf
# Linguist language overrides
*.js linguist-language=JavaScript
*.jsm linguist-language=JavaScript
*.inc linguist-language=XML

1
.github/CODEOWNERS vendored
View File

@ -1 +0,0 @@
l10n/en-US/*.ftl @mozilla/pdfjs-l10n

View File

@ -1,17 +0,0 @@
Attach (recommended) or Link to PDF file here:
Configuration:
- Web browser and its version:
- Operating system and its version:
- PDF.js version:
- Is a browser extension:
Steps to reproduce the problem:
1.
2.
What is the expected behavior? (add screenshot)
What went wrong? (add screenshot)
Link to a viewer (if hosted on a site other than mozilla.github.io/pdf.js or as Firefox/Chrome extension):

View File

@ -1,8 +0,0 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
labels:
- "dependencies"

View File

@ -1,27 +0,0 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# See https://github.com/mozilla-l10n/moz-fluent-linter/blob/main/src/fluent_linter/config.yml
# for details
---
ID01:
enabled: true
exclusions:
messages: []
files: []
ID02:
enabled: true
min_length: 9
exclusions:
messages: []
files: []
CO01:
enabled: true
brands:
- Firefox
- Mozilla
exclusions:
files: []
messages: []

View File

@ -1 +0,0 @@
moz-fluent-linter==0.4.*

View File

@ -1,37 +0,0 @@
name: CI
on: [push, pull_request]
permissions:
contents: read
jobs:
test:
name: Test
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node-version: [18, lts/*, latest]
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Install Gulp
run: npm install -g gulp-cli
- name: Install other dependencies
run: npm install
- name: Run external tests
run: gulp externaltest
- name: Run CLI unit tests
run: gulp unittestcli

View File

@ -1,35 +0,0 @@
name: CodeQL
on: [push, pull_request]
permissions:
contents: read
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
security-events: write
strategy:
fail-fast: false
matrix:
language: [javascript]
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
queries: security-and-quality
- name: Autobuild CodeQL
uses: github/codeql-action/autobuild@v3
- name: Perform CodeQL analysis
uses: github/codeql-action/analyze@v3

View File

@ -1,42 +0,0 @@
name: Lint Fluent Reference Files
on:
push:
paths:
- 'l10n/en-US/**.ftl'
- '.github/fluent_linter_config.yml'
- '.github/workflows/fluent_linter.yml'
branches:
- master
pull_request:
paths:
- 'l10n/en-US/**.ftl'
- '.github/fluent_linter_config.yml'
- '.github/workflows/fluent_linter.yml'
branches:
- master
workflow_dispatch:
permissions:
contents: read
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Use Python 3.12
uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'pip'
- name: Install Fluent dependencies
run: |
pip install -r .github/requirements.txt
- name: Lint Fluent reference files
run: |
moz-fluent-lint ./l10n/en-US --config .github/fluent_linter_config.yml

View File

@ -1,64 +0,0 @@
name: Font tests
on:
push:
paths:
- 'gulpfile.mjs'
- 'src/**'
- 'test/test.mjs'
- 'test/font/**'
- '.github/workflows/font_tests.yml'
branches:
- master
pull_request:
paths:
- 'gulpfile.mjs'
- 'src/**'
- 'test/test.mjs'
- 'test/font/**'
- '.github/workflows/font_tests.yml'
branches:
- master
workflow_dispatch:
permissions:
contents: read
jobs:
test:
name: Test
strategy:
fail-fast: false
matrix:
node-version: [lts/*]
os: [windows-latest, ubuntu-latest]
runs-on: ${{ matrix.os }}
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Install Gulp
run: npm install -g gulp-cli
- name: Install other dependencies
run: npm install
- name: Use Python 3.12
uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'pip'
- name: Install Fonttools
run: pip install fonttools
- name: Run font tests
run: gulp fonttest --headless

View File

@ -1,37 +0,0 @@
name: Lint
on: [push, pull_request]
permissions:
contents: read
jobs:
lint:
name: Lint
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node-version: [lts/*]
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Install Gulp
run: npm install -g gulp-cli
- name: Install other dependencies
run: npm install
- name: Run lint
run: gulp lint
- name: Run lint-chromium
run: gulp lint-chromium

View File

@ -1,72 +0,0 @@
name: Publish website
on:
push:
branches:
- master
permissions:
contents: read
jobs:
build:
name: Build
runs-on: ubuntu-latest
strategy:
matrix:
node-version: [lts/*]
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Install Gulp
run: npm install -g gulp-cli
- name: Install other dependencies
run: npm install
- name: Build the website
run: gulp web
- name: Archive the website
shell: sh
run: |
chmod -c -R +rX "$INPUT_PATH" | while read line; do
echo "::warning title=Invalid file permissions automatically fixed::$line"
done
tar \
--dereference --hard-dereference \
--directory "$INPUT_PATH" \
-cvf "$RUNNER_TEMP/website.tar" \
--exclude=.git \
--exclude=.github \
.
env:
INPUT_PATH: build/gh-pages
- name: Upload the website
uses: actions/upload-artifact@v4
with:
name: github-pages
path: ${{ runner.temp }}/website.tar
retention-days: 1
if-no-files-found: error
deploy:
name: Deploy
runs-on: ubuntu-latest
needs: build
permissions:
pages: write # Required to deploy to GitHub Pages.
id-token: write # Required to verify that the deployment originates from this workflow.
steps:
- name: Deploy the website
uses: actions/deploy-pages@v4

View File

@ -1,34 +0,0 @@
name: Types tests
on: [push, pull_request]
permissions:
contents: read
jobs:
test:
name: Test
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
node-version: [lts/*]
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- name: Install Gulp
run: npm install -g gulp-cli
- name: Install other dependencies
run: npm install
- name: Run types tests
run: gulp typestest

1
.gitignore vendored
View File

@ -6,4 +6,3 @@ tags
Makefile
node_modules/
examples/node/svgdump/
examples/node/pdf2png/*.png

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "test/ttx/fonttools-code"]
path = test/ttx/fonttools-code
url = git://git.code.sf.net/p/fonttools/code

7
.gitpod.Dockerfile vendored
View File

@ -1,7 +0,0 @@
FROM gitpod/workspace-full-vnc
USER gitpod
RUN sudo apt-get update && \
sudo apt-get install -yq firefox && \
sudo rm -rf /var/lib/apt/lists/*

View File

@ -1,13 +0,0 @@
image:
file: .gitpod.Dockerfile
tasks:
- command: |
gp await-port 8888 && gp preview $(gp url 8888)/web/viewer.html && echo '[{"name": "Firefox","path": "/usr/bin/firefox"}]' | jq '.' > test/resources/browser_manifests/browser_manifest.json
- init: npm install -g gulp-cli && npm install
command: gulp server
ports:
- port: 8888
onOpen: ignore
- port: 6080
onOpen: ignore

18
.jshintignore Normal file
View File

@ -0,0 +1,18 @@
build/
l10n/
docs/
node_modules/
examples/
external/webL10n/
external/shelljs/
external/jpgjs/
external/jasmine/
external/cmapscompress/
external/importL10n/
shared/
test/tmp/
test/features/
test/resources/
test/mozcentral/
test/font/*_spec.js
*~/

26
.jshintrc Normal file
View File

@ -0,0 +1,26 @@
{
// Environments
"browser": true,
"devel": true,
"worker": true,
// Enforcing
"maxlen": 80,
"quotmark": "single",
"trailing": true,
"curly": true,
"undef": true,
"noarg": true,
"nonbsp": true,
"eqeqeq": true,
// Relaxing
"boss": true,
"funcscope": true,
"globalstrict": true,
"loopfunc": true,
"maxerr": 1000,
"nonstandard": true,
"sub": true,
"validthis": true
}

View File

@ -1 +0,0 @@
Michał Gołębiowski-Owczarek <m.goleb@gmail.com>

View File

@ -1,12 +0,0 @@
build/
l10n/
docs/
node_modules/
external/bcmaps/
external/builder/fixtures/
external/builder/fixtures_esprima/
external/quickjs/
test/tmp/
test/pdfs/
web/locale/
*~/

View File

@ -1,18 +0,0 @@
{
"arrowParens": "avoid",
"endOfLine": "lf",
"printWidth": 80,
"semi": true,
"tabWidth": 2,
"trailingComma": "es5",
"useTabs": false,
"overrides": [
{
files: ["tsconfig.json"],
options: {
parser: "json",
},
},
]
}

View File

@ -1,12 +0,0 @@
build/
l10n/
docs/
node_modules/
external/bcmaps/
external/builder/fixtures/
external/builder/fixtures_esprima/
external/quickjs/
test/tmp/
test/pdfs/
web/locale/
*~/

View File

@ -1,25 +0,0 @@
{
"plugins": [
"stylelint-prettier"
],
"rules": {
"prettier/prettier": true,
"alpha-value-notation": "number",
"block-no-empty": true,
"color-function-notation": "modern",
"color-hex-length": "short",
"color-no-invalid-hex": true,
"declaration-block-no-duplicate-properties": true,
"declaration-block-no-redundant-longhand-properties": true,
"declaration-property-value-disallowed-list": {
"float": ["inline-start", "inline-end"]
},
"length-zero-no-unit": [true, {
ignore: ["custom-properties"]
}],
"selector-pseudo-element-colon-notation": "double",
"shorthand-property-no-redundant-values": true,
},
}

3
.travis.yml Normal file
View File

@ -0,0 +1,3 @@
language: node_js
node_js:
- "0.10"

View File

@ -16,13 +16,10 @@ Jonas Jenwald <jonas.jenwald@gmail.com>
Julian Viereck
Justin D'Arcangelo <justindarc@gmail.com>
Kalervo Kujala
Michał Gołębiowski-Owczarek <m.goleb@gmail.com>
Ophir Lojkine <@lovasoa>
Rob Wu <rob@robwu.nl>
Shaon Barman <shaon.barman@gmail.com>
Sehyun Park <premed055515@gmail.com>
Tim van der Meij <info@timvandermeij.nl>
Vivin Paliath <vivin.paliath@gmail.com>
Vivien Nicolas <21@vingtetun.org>
Yury Delendik <ydelendik@mozilla.com>
waddlesplash <@waddlesplash>

View File

@ -1,15 +0,0 @@
# Community Participation Guidelines
This repository is governed by Mozilla's code of conduct and etiquette guidelines.
For more details, please read the
[Mozilla Community Participation Guidelines](https://www.mozilla.org/about/governance/policies/participation/).
## How to Report
For more information on how to report violations of the Community Participation Guidelines, please read our '[How to Report](https://www.mozilla.org/about/governance/policies/participation/reporting/)' page.
<!--
## Project Specific Etiquette
In some cases, there will be additional project etiquette i.e.: (https://bugzilla.mozilla.org/page.cgi?id=etiquette.html).
Please update for your project.
-->

View File

@ -2,13 +2,11 @@
The issues are used to track both bugs filed by users and specific work items for developers. Try to file one issue per problem observed. Please specify a valid title (e.g. "Glyph spacing is incorrect" instead of "PDF.js does not work") and provide more details about the issue: link to the PDF, location in the PDF, screenshot, browser version, operating system, PDF.js version and JavaScript console warning/error messages. Issues that do not have enough details provided will be closed as invalid/incomplete.
If the issue is related to errors produced by a specific PDF, please always include the PDF by providing a URL where contributors can download it. Without a PDF for reproduction, such issues will be closed. We understand that many PDFs contain sensitive information, however having a PDF is essential to resolving the issue and building our regression testing suite. If possible, try creating a reduced example exhibiting the problem but not containing sensitive data. Also small PDFs are best suited for our regression testing. If an important issue only shows on sensitive PDFs, contributors might be willing to accept these PDFs via a secure exchange.
The issue tracking system is designed to record a single technical problem. A bug report is something where a developer/contributor can work on. The GitHub issue tracker is not a good place for general, not well thought out or unworkable ideas. Most likely a discussion-type issue will not be addressed for a long time or closed as invalid. The best place is our dev-pdf-js@lists.mozilla.org mailing list. You can subscribe to it using http://lists.mozilla.org or Google Groups. This way you will reach not only developers. As an alternative, you can join our weekly engineering meeting to discuss new ideas for the project.
The issue tracking system is designed to record a single technical problem. A bug report is something where a developer/contributor can work on. The GitHub issue tracker is not a good place for general, not well thought out or unworkable ideas. Most likely a discussion-type issue will not be addressed for a long time or closed as invalid. The best place for general discussions is our Matrix room at https://chat.mozilla.org/#/room/#pdfjs:mozilla.org.
If you are developing a custom solution, first check the examples at https://github.com/mozilla/pdf.js#learning and search existing issues. If this does not help, please prepare a short well-documented example that demonstrates the problem and make it accessible online on your website, JS Bin, GitHub, etc. before opening a new issue or contacting us on the IRC channel -- keep in mind that just code snippets won't help us troubleshoot the problem.
If you are developing a custom solution, first check the examples at https://github.com/mozilla/pdf.js#learning and search existing issues. If this does not help, please prepare a short well-documented example that demonstrates the problem and make it accessible online on your website, JS Bin, GitHub, etc. before opening a new issue or contacting us in the Matrix room -- keep in mind that just code snippets won't help us troubleshoot the problem.
Note that the translations for PDF.js in the `l10n` folder are imported from the Nightly channel of Mozilla Firefox, such that we don't have to maintain them ourselves. This means that we will not accept pull requests that add new languages and/or modify existing translations, unless the corresponding changes have been made in Mozilla Firefox first.
Note that the translations for PDF.js in the `l10n` folder are synchronized with the Aurora branch of Mozilla Firefox. This means that we will only accept pull requests that add strings currently missing in the Aurora branch (because it will take at least six weeks before the most recent translations are in the Aurora branch), but keep in mind that the changes will be overwritten when we synchronize again.
See also:
- https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions

5
EXPORT
View File

@ -1,5 +0,0 @@
PDF.js is publicly available software not subject to the Export Administration
Regulations (EAR) per EAR 734.3(b) and 734.7. Because PDF.js is not subject
to the EAR it does not have an Export Control Classification Number (ECCN).
Mozilla has completed the notification for PDF.js publicly available encryption
source code per EAR 742.15(b).

View File

@ -175,3 +175,4 @@
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

152
README.md
View File

@ -1,146 +1,136 @@
# PDF.js [![Build Status](https://github.com/mozilla/pdf.js/workflows/CI/badge.svg?branch=master)](https://github.com/mozilla/pdf.js/actions?query=workflow%3ACI+branch%3Amaster)
# PDF.js
[PDF.js](https://mozilla.github.io/pdf.js/) is a Portable Document Format (PDF) viewer that is built with HTML5.
PDF.js is a Portable Document Format (PDF) viewer that is built with HTML5.
PDF.js is community-driven and supported by Mozilla. Our goal is to
PDF.js is community-driven and supported by Mozilla Labs. Our goal is to
create a general-purpose, web standards-based platform for parsing and
rendering PDFs.
## Contributing
PDF.js is an open source project and always looking for more contributors. To
get involved, visit:
get involved checkout:
+ [Issue Reporting Guide](https://github.com/mozilla/pdf.js/blob/master/.github/CONTRIBUTING.md)
+ [Code Contribution Guide](https://github.com/mozilla/pdf.js/wiki/Contributing)
+ [Frequently Asked Questions](https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions)
+ [Good Beginner Bugs](https://github.com/mozilla/pdf.js/issues?direction=desc&labels=good-beginner-bug&page=1&sort=created&state=open)
+ [Projects](https://github.com/mozilla/pdf.js/projects)
+ [Workflow](https://github.com/mozilla/pdf.js/wiki/Contributing)
+ [Style Guide](https://github.com/mozilla/pdf.js/wiki/Style-Guide)
+ [FAQ](https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions)
+ [Good Beginner Bugs](https://github.com/mozilla/pdf.js/issues?direction=desc&labels=5-good-beginner-bug&page=1&sort=created&state=open)
+ [Priorities](https://github.com/mozilla/pdf.js/milestones)
+ [Attend a Public Meeting](https://github.com/mozilla/pdf.js/wiki/Weekly-Public-Meetings)
Feel free to stop by our [Matrix room](https://chat.mozilla.org/#/room/#pdfjs:mozilla.org) for questions or guidance.
For further questions or guidance feel free to stop by #pdfjs on
irc.mozilla.org.
## Getting Started
### Online demo
Please note that the "Modern browsers" version assumes native support for the
latest JavaScript features; please also see [this wiki page](https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions#faq-support).
+ Modern browsers: https://mozilla.github.io/pdf.js/web/viewer.html
+ Older browsers: https://mozilla.github.io/pdf.js/legacy/web/viewer.html
+ http://mozilla.github.io/pdf.js/web/viewer.html
### Browser Extensions
#### Firefox
PDF.js is built into version 19+ of Firefox.
PDF.js is built into version 19+ of Firefox, however one extension is still available:
#### Chrome
+ [Development Version](http://mozilla.github.io/pdf.js/extensions/firefox/pdf.js.xpi) - This version is updated every time new code is merged into the PDF.js codebase. This should be quite stable but still might break from time to time.
+ The official extension for Chrome can be installed from the [Chrome Web Store](https://chrome.google.com/webstore/detail/pdf-viewer/oemmndcbldboiebfnladdacbdfmadadm).
*This extension is maintained by [@Rob--W](https://github.com/Rob--W).*
+ Build Your Own - Get the code as explained below and issue `gulp chromium`. Then open
#### Chrome and Opera
The Chromium extension is still somewhat experimental but it can be installed two
ways:
+ [Unofficial Version](https://chrome.google.com/webstore/detail/pdf-viewer/oemmndcbldboiebfnladdacbdfmadadm) - *This extension is maintained by a PDF.js contributor.*
+ Build Your Own - Get the code as explained below and issue `node make chromium`. Then open
Chrome, go to `Tools > Extension` and load the (unpackaged) extension from the
directory `build/chromium`.
The version of the extension for the Opera browser can be found at the [Opera add-ons catalog](https://addons.opera.com/en/extensions/details/pdf-viewer/).
## Getting the Code
To get a local copy of the current code, clone it using git:
$ git clone https://github.com/mozilla/pdf.js.git
$ cd pdf.js
$ git clone git://github.com/mozilla/pdf.js.git pdfjs
$ cd pdfjs
Next, install Node.js via the [official package](https://nodejs.org) or via
[nvm](https://github.com/creationix/nvm). You need to install the gulp package
globally (see also [gulp's getting started](https://github.com/gulpjs/gulp/tree/master/docs/getting-started)):
Next, you need to start a local web server as some browsers don't allow opening
PDF files for a file:// url:
$ npm install -g gulp-cli@^2.3.0
$ node make server
If you prefer to not install `gulp-cli` globally, you have to prefix all the `gulp` commands with `npx` (for example, `npx gulp server` instead of `gulp server`).
If everything worked out, install all dependencies for PDF.js:
$ npm install
> [!NOTE]
> On MacOS M1/M2 you may see some `node-gyp`-related errors when running `npm install`. This is because one of our dependencies, `"canvas"`, does not provide pre-built binaries for this platform and instead `npm` will try to build it from source. Please make sure to first install the necessary native dependencies using `brew`: https://github.com/Automattic/node-canvas#compiling.
Finally, you need to start a local web server as some browsers do not allow opening
PDF files using a `file://` URL. Run:
$ gulp server
and then you can open:
You can install Node via [nvm](https://github.com/creationix/nvm) or the
[official package](http://nodejs.org). If everything worked out, you can now
serve
+ http://localhost:8888/web/viewer.html
Please keep in mind that this assumes the latest version of Mozilla Firefox; refer to [Building PDF.js](https://github.com/mozilla/pdf.js/blob/master/README.md#building-pdfjs) for non-development usage of the PDF.js library.
It is also possible to view all test PDF files on the right side by opening:
You can also view all the test pdf files on the right side serving
+ http://localhost:8888/test/pdfs/?frame
## Building PDF.js
In order to bundle all `src/` files into two production scripts and build the generic
viewer, run:
In order to bundle all `src/` files into two productions scripts and build the generic
viewer, issue:
$ gulp generic
$ node make generic
If you need to support older browsers, run:
$ gulp generic-legacy
This will generate `pdf.js` and `pdf.worker.js` in the `build/generic/build/` directory (respectively `build/generic-legacy/build/`).
This will generate `pdf.js` and `pdf.worker.js` in the `build/generic/build/` directory.
Both scripts are needed but only `pdf.js` needs to be included since `pdf.worker.js` will
be loaded by `pdf.js`. The PDF.js files are large and should be minified for production.
## Using PDF.js in a web application
To use PDF.js in a web application you can choose to use a pre-built version of the library
or to build it from source. We supply pre-built versions for usage with NPM and Bower under
the `pdfjs-dist` name. For more information and examples please refer to the
[wiki page](https://github.com/mozilla/pdf.js/wiki/Setup-pdf.js-in-a-website) on this subject.
## Including via a CDN
PDF.js is hosted on several free CDNs:
- https://www.jsdelivr.com/package/npm/pdfjs-dist
- https://cdnjs.com/libraries/pdf.js
- https://unpkg.com/pdfjs-dist/
be loaded by `pdf.js`. If you want to support more browsers than Firefox you'll also need
to include `compatibility.js` from `build/generic/web/`. The PDF.js files are large and
should be minified for production.
## Learning
You can play with the PDF.js API directly from your browser using the live demos below:
You can play with the PDF.js API directly from your browser through the live
demos below:
+ [Interactive examples](https://mozilla.github.io/pdf.js/examples/index.html#interactive-examples)
+ [Hello world](http://mozilla.github.io/pdf.js/examples/learning/helloworld.html)
+ [Simple reader with prev/next page controls](http://mozilla.github.io/pdf.js/examples/learning/prevnext.html)
More examples can be found in the [examples folder](https://github.com/mozilla/pdf.js/tree/master/examples/). Some of them are using the pdfjs-dist package, which can be built and installed in this repo directory via `gulp dist-install` command.
The repo contains a hello world example that you can run locally:
+ [examples/helloworld/](https://github.com/mozilla/pdf.js/blob/master/examples/helloworld/)
For an introduction to the PDF.js code, check out the presentation by our
contributor Julian Viereck:
+ https://www.youtube.com/watch?v=Iv15UY-4Fg8
+ http://www.youtube.com/watch?v=Iv15UY-4Fg8
More learning resources can be found at:
You can read more about PDF.js here:
+ http://andreasgal.com/2011/06/15/pdf-js/
+ http://blog.mozilla.com/cjones/2011/06/15/overview-of-pdf-js-guts/
Even more learning resources can be found at:
+ https://github.com/mozilla/pdf.js/wiki/Additional-Learning-Resources
The API documentation can be found at:
+ https://mozilla.github.io/pdf.js/api/
## Questions
Check out our FAQs and get answers to common questions:
+ https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions
Talk to us on Matrix:
Talk to us on IRC:
+ https://chat.mozilla.org/#/room/#pdfjs:mozilla.org
+ #pdfjs on irc.mozilla.org
File an issue:
Join our mailing list:
+ https://github.com/mozilla/pdf.js/issues/new
+ dev-pdf-js@lists.mozilla.org
Subscribe either using lists.mozilla.org or Google Groups:
+ https://lists.mozilla.org/listinfo/dev-pdf-js
+ https://groups.google.com/group/mozilla.dev.pdf-js/topics
Follow us on twitter: @pdfjs
+ http://twitter.com/#!/pdfjs
Weekly Public Meetings
+ https://github.com/mozilla/pdf.js/wiki/Weekly-Public-Meetings

View File

@ -5,6 +5,8 @@
"description": ""
},
"require": {
"moment": "moment",
"_": "underscore",
"typogr": "typogr"
},
"jade": {

View File

@ -5,26 +5,22 @@ template: layout.jade
## Hello World Walkthrough
[Full source](https://github.com/mozilla/pdf.js/blob/master/examples/learning/helloworld.html)
[Full source](https://github.com/mozilla/pdf.js/tree/master/examples/helloworld)
PDF.js heavily relies on the use of [Promises](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise). If promises are new to you, it's recommended you become familiar with them before continuing on.
This tutorial shows how PDF.js can be used as a library in a web browser.
[examples/](https://github.com/mozilla/pdf.js/tree/master/examples) provides more examples, including usage in Node.js (at [examples/node/](https://github.com/mozilla/pdf.js/tree/master/examples/node)).
### Document
The object structure of PDF.js loosely follows the structure of an actual PDF. At the top level there is a document object. From the document, more information and individual pages can be fetched. To get the document:
```js
pdfjsLib.getDocument('helloworld.pdf')
PDFJS.getDocument('helloworld.pdf')
```
Remember though that PDF.js uses promises, and the above will return a `PDFDocumentLoadingTask` instance that has a `promise` property which is resolved with the document object.
Remember though that PDF.js uses promises, so the above will return a promise that is resolved with the document object.
```js
var loadingTask = pdfjsLib.getDocument('helloworld.pdf');
loadingTask.promise.then(function(pdf) {
PDFJS.getDocument('helloworld.pdf').then(function(pdf) {
// you can now use *pdf* here
});
```
@ -39,29 +35,19 @@ pdf.getPage(1).then(function(page) {
```
### Rendering the Page
Each PDF page has its own viewport which defines the size in pixels(72DPI) and initial rotation. By default the viewport is scaled to the original size of the PDF, but this can be changed by modifying the viewport. When the viewport is created, an initial transformation matrix will also be created that takes into account the desired scale, rotation, and it transforms the coordinate system (the 0,0 point in PDF documents the bottom-left whereas canvas 0,0 is top-left).
Each PDF page has its own viewport which defines the size in pixels(72DPI) and initial rotation. By default the viewport is scaled to the original size of the PDF, but this can be changed by modifying the viewport. When the viewport is created an initial transformation matrix will also be created that takes into account the desired scale, rotation, and it transforms the coordinate system (the 0,0 point in PDF documents the bottom-left whereas canvas 0,0 is top-left).
```js
var scale = 1.5;
var viewport = page.getViewport({ scale: scale, });
// Support HiDPI-screens.
var outputScale = window.devicePixelRatio || 1;
var viewport = page.getViewport(scale);
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;
canvas.height = viewport.height;
canvas.width = viewport.width;
var renderContext = {
canvasContext: context,
transform: transform,
viewport: viewport
};
page.render(renderContext);
@ -71,29 +57,9 @@ Alternatively, if you want the canvas to render to a certain pixel size you coul
```js
var desiredWidth = 100;
var viewport = page.getViewport({ scale: 1, });
var viewport = page.getViewport(1);
var scale = desiredWidth / viewport.width;
var scaledViewport = page.getViewport({ scale: scale, });
var scaledViewport = page.getViewport(scale);
```
## Interactive examples
### Hello World with document load error handling
The example demonstrates how promises can be used to handle errors during loading.
It also demonstrates how to wait until a page is loaded and rendered.
<script async src="//jsfiddle.net/pdfjs/9engc9mw/embed/html,css,result/"></script>
### Hello World using base64 encoded PDF
The PDF.js can accept any decoded base64 data as an array.
<script async src="//jsfiddle.net/pdfjs/cq0asLqz/embed/html,css,result/"></script>
### Previous/Next example
The same canvas cannot be used to perform to draw two pages at the same time --
the example demonstrates how to wait on previous operation to be complete.
<script async src="//jsfiddle.net/pdfjs/wagvs9Lf/embed/html,css,result/"></script>

View File

@ -21,7 +21,7 @@ Before downloading PDF.js please take a moment to understand the different layer
<tbody>
<tr>
<td>Core</td>
<td>The core layer is where a binary PDF is parsed and interpreted. This layer is the foundation for all subsequent layers. It is not documented here because using it directly is considered an advanced usage and the API is likely to change. For an example of using the core layer see the <a href="https://github.com/brendandahl/pdf.js.utils/tree/master/browser">PDF Object Browser</a>.
<td>The core layer is where a binary PDF is parsed and interpreted. This layer is the foundation for all subsequent layers. It is not documented here because using it directly is considered an advanced usage and the API is likely to change. For an example of using the core layer see the [PDF Object Browser](https://github.com/brendandahl/pdf.js.utils/tree/master/browser)
</td>
</tr>
<tr>
@ -30,98 +30,85 @@ Before downloading PDF.js please take a moment to understand the different layer
</tr>
<tr>
<td>Viewer</td>
<td>The viewer is built on the display layer and is the UI for PDF viewer in Firefox and the other browser extensions within the project. It can be a good starting point for building your own viewer. <em>However, we do ask if you plan to embed the viewer in your own site, that it not just be an unmodified version. Please re-skin it or build upon it.</em></td>
<td>The viewer is built on the display layer and is the UI for PDF viewer in Firefox and the other browser extensions within the project. It can be a good starting point for building your own viewer. *However, we do ask if you plan to embed the viewer in your own site, that it not just be an unmodified version. Please re-skin it or build upon it.*</td>
</tr>
</tbody>
</table>
## Download
Please refer to [this wiki page](https://github.com/mozilla/pdf.js/wiki/Frequently-Asked-Questions#faq-support) for information about supported browsers.
<div class="row">
<div class="col-md-4">
<h3>Prebuilt (modern browsers)</h3>
<div class="col-md-6">
<h3>Pre-built</h3>
<p>
Includes the generic build of PDF.js and the viewer.
</p>
<a type="button" class="btn btn-primary" href="https://github.com/mozilla/pdf.js/releases/download/vSTABLE_VERSION/pdfjs-STABLE_VERSION-dist.zip">Stable (vSTABLE_VERSION)</a>
<span class="btn-group-vertical centered">
<a type="button" class="btn btn-primary" href="https://github.com/mozilla/pdf.js/releases/download/vSTABLE_VERSION/pdfjs-STABLE_VERSION-dist.zip">Stable (vSTABLE_VERSION)</a>
<a type="button" class="btn btn-warning" href="https://github.com/mozilla/pdf.js/releases/download/vBETA_VERSION/pdfjs-BETA_VERSION-dist.zip">Beta (vBETA_VERSION)</a>
</span>
</div>
<div class="col-md-4">
<h3>Prebuilt (older browsers)</h3>
<p>
Includes the generic build of PDF.js and the viewer.
</p>
<a type="button" class="btn btn-primary" href="https://github.com/mozilla/pdf.js/releases/download/vSTABLE_VERSION/pdfjs-STABLE_VERSION-legacy-dist.zip">Stable (vSTABLE_VERSION)</a>
</div>
<div class="col-md-4">
<div class="col-md-6">
<h3>Source</h3>
To get a local copy of the current code, clone it using git:
<pre><code>$ git clone https://github.com/mozilla/pdf.js.git
$ cd pdf.js
<pre><code>$ git clone git://github.com/mozilla/pdf.js.git pdfjs
$ cd pdfjs
</code></pre>
</div>
</div>
## Including via a CDN
PDF.js is hosted on several free CDNs:
- https://www.jsdelivr.com/package/npm/pdfjs-dist
- https://cdnjs.com/libraries/pdf.js
- https://unpkg.com/pdfjs-dist/
## File Layout Overview
Note that we only mention the most relevant files and folders.
### Prebuilt
```
├── LICENSE
├── build/
│   ├── pdf.js - display layer
│   ├── pdf.js.map - display layer's source map
│   ├── pdf.worker.js - core layer
│   └── pdf.worker.js.map - core layer's source map
├── web/
│ ├── cmaps/ - character maps (required by core)
│ ├── compressed.tracemonkey-pldi-09.pdf - PDF file for testing purposes
│ ├── debugger.js - helpful debugging features
│ ├── images/ - images for the viewer and annotation icons
│ ├── locale/ - translation files
│ ├── viewer.css - viewer style sheet
│ ├── viewer.html - viewer layout
│ ├── viewer.js - viewer layer
│ └── viewer.js.map - viewer layer's source map
└── LICENSE
│   └── pdf.worker.js - core layer
└── web/
├── cmaps/ - character maps(required by core)
├── compatibility.js - polyfills for missing features
├── compressed.tracemonkey-pldi-09.pdf - test pdf
├── debugger.js - helpful pdf debugging features
├── images/ - images for the viewer and annotation icons
├── l10n.js - localization
├── locale/ - translation files
├── viewer.css - viewer style sheet
├── viewer.html - viewer html
└── viewer.js - viewer layer
```
### Source
```
├── docs/ - website source code
├── examples/ - simple usage examples
├── extensions/ - browser extension source code
├── AUTHORS
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── build/ - output of build steps (empty)
├── docs/ - this
├── examples/ - bare bones examples
├── extensions/ - various browser extensions
├── external/ - third party code
├── l10n/ - translation files
├── make.js - build script
├── package.json
├── src/
│   ├── core/ - core layer
│   ├── display/ - display layer
│   ├── shared/ - shared code between the core and display layers
│   ├── interfaces.js - interface definitions for the core/display layers
│   └── pdf.*.js - wrapper files for bundling
├── test/ - unit, font, reference, and integration tests
├── web/ - viewer layer
├── LICENSE
├── README.md
├── gulpfile.js - build scripts/logic
├── package-lock.json - pinned dependency versions
└── package.json - package definition and dependencies
│   ├── images/
│   ├── pdf.js - wrapper file that everything is bundled into
│   ├── shared/ - shared code between core and display layers
│   └── worker_loader.js - used for developer builds to load worker files
├── test/ - reference, unit, and font tests
└── web/ - viewer layer
```
## Trying the Viewer
With the prebuilt or source version, open `web/viewer.html` in a browser and the test pdf should load. Note: the worker is not enabled for file:// urls, so use a server. If you're using the source build and have node, you can run `gulp server`.
With the prebuilt or source version open `web/viewer.html` in a browser and the test pdf should load. Note: the worker is not enabled for file:// urls, so use a server. If you're using the source build and have node, you can run `node make server`.
## More Information
For a further walkthrough of a minimal viewer, see the hello world example. More documentation can be found in our [wiki](https://github.com/mozilla/pdf.js/wiki) too.
For a further walkthrough of a minimal viewer see the hello world example. More documentation can be found in our [wiki](https://github.com/mozilla/pdf.js/wiki) too.

View File

@ -9,6 +9,6 @@ template: layout.jade
</p>
<p class="text-center">
<a type="button" class="btn btn-lg btn-default" href="getting_started/#download">Download</a>
<a type="button" class="btn btn-lg btn-default" href="https://github.com/mozilla/pdf.js#online-demo">Demo</a>
<a type="button" class="btn btn-lg btn-default" href="https://github.com/mozilla/pdf.js">GitHub Project</a>
<a type="button" class="btn btn-lg btn-default" href="web/viewer.html">Demo</a>
<a type="button" class="btn btn-lg btn-default" href="https://github.com/mozilla/pdf.js">Github Project</a>
</p>

View File

@ -10,6 +10,6 @@ module.exports = (env, callback) ->
depth = count(source, '/') # 1 being /
ret = ""
ret += "../" while depth = depth - 1
ret + dest.substring(1)
ret + dest.substr(1)
callback()

View File

@ -4,7 +4,7 @@ html(lang='en')
head
meta(charset='utf-8')
meta(name='viewport', content='width=device-width, initial-scale=1.0')
meta(name='description', content='A general-purpose, web standards-based platform for parsing and rendering PDFs.')
meta(name='description', content='')
meta(name='author', content='')
link(rel='shortcut icon', href=makeRelative(page.url, '/images/favicon.ico'))
title=page.title
@ -43,9 +43,9 @@ html(lang='en')
.container
footer
p &copy;Mozilla and individual contributors
:markdown-it
:markdown
PDF.js is licensed under [Apache](https://github.com/mozilla/pdf.js/blob/master/LICENSE),
documentation is licensed under [CC BY-SA 2.5](https://creativecommons.org/licenses/by-sa/2.5/)
documentation is licensed under [CC BY-SA 2.5](http://creativecommons.org/licenses/by-sa/2.5/)
// Bootstrap core JavaScript
script(src=makeRelative(page.url, '/js/jquery-2.1.0.min.js'))

View File

@ -1,11 +0,0 @@
{
"extends": [
"../.eslintrc"
],
"globals": {
"pdfjsImageDecoders": false,
"pdfjsLib": false,
"pdfjsViewer": false,
},
}

153
examples/acroforms/forms.js Normal file
View File

@ -0,0 +1,153 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
//
// Basic AcroForms input controls rendering
//
'use strict';
var formFields = {};
function setupForm(div, content, viewport) {
function bindInputItem(input, item) {
if (input.name in formFields) {
var value = formFields[input.name];
if (input.type == 'checkbox') {
input.checked = value;
} else if (!input.type || input.type == 'text') {
input.value = value;
}
}
input.onchange = function pageViewSetupInputOnBlur() {
if (input.type == 'checkbox') {
formFields[input.name] = input.checked;
} else if (!input.type || input.type == 'text') {
formFields[input.name] = input.value;
}
};
}
function createElementWithStyle(tagName, item) {
var element = document.createElement(tagName);
var rect = PDFJS.Util.normalizeRect(
viewport.convertToViewportRectangle(item.rect));
element.style.left = Math.floor(rect[0]) + 'px';
element.style.top = Math.floor(rect[1]) + 'px';
element.style.width = Math.ceil(rect[2] - rect[0]) + 'px';
element.style.height = Math.ceil(rect[3] - rect[1]) + 'px';
return element;
}
function assignFontStyle(element, item) {
var fontStyles = '';
if ('fontSize' in item) {
fontStyles += 'font-size: ' + Math.round(item.fontSize *
viewport.fontScale) + 'px;';
}
switch (item.textAlignment) {
case 0:
fontStyles += 'text-align: left;';
break;
case 1:
fontStyles += 'text-align: center;';
break;
case 2:
fontStyles += 'text-align: right;';
break;
}
element.setAttribute('style', element.getAttribute('style') + fontStyles);
}
content.getAnnotations().then(function(items) {
for (var i = 0; i < items.length; i++) {
var item = items[i];
switch (item.subtype) {
case 'Widget':
if (item.fieldType != 'Tx' && item.fieldType != 'Btn' &&
item.fieldType != 'Ch') {
break;
}
var inputDiv = createElementWithStyle('div', item);
inputDiv.className = 'inputHint';
div.appendChild(inputDiv);
var input;
if (item.fieldType == 'Tx') {
input = createElementWithStyle('input', item);
}
if (item.fieldType == 'Btn') {
input = createElementWithStyle('input', item);
if (item.flags & 32768) {
input.type = 'radio';
// radio button is not supported
} else if (item.flags & 65536) {
input.type = 'button';
// pushbutton is not supported
} else {
input.type = 'checkbox';
}
}
if (item.fieldType == 'Ch') {
input = createElementWithStyle('select', item);
// select box is not supported
}
input.className = 'inputControl';
input.name = item.fullName;
input.title = item.alternativeText;
assignFontStyle(input, item);
bindInputItem(input, item);
div.appendChild(input);
break;
}
}
});
}
function renderPage(div, pdf, pageNumber, callback) {
pdf.getPage(pageNumber).then(function(page) {
var scale = 1.5;
var viewport = page.getViewport(scale);
var pageDisplayWidth = viewport.width;
var pageDisplayHeight = viewport.height;
var pageDivHolder = document.createElement('div');
pageDivHolder.className = 'pdfpage';
pageDivHolder.style.width = pageDisplayWidth + 'px';
pageDivHolder.style.height = pageDisplayHeight + 'px';
div.appendChild(pageDivHolder);
// Prepare canvas using PDF page dimensions
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
canvas.width = pageDisplayWidth;
canvas.height = pageDisplayHeight;
pageDivHolder.appendChild(canvas);
// Render PDF page into canvas context
var renderContext = {
canvasContext: context,
viewport: viewport
};
page.render(renderContext).promise.then(callback);
// Prepare and populate form elements layer
var formDiv = document.createElement('div');
pageDivHolder.appendChild(formDiv);
setupForm(formDiv, page, viewport);
});
}
// Fetch the PDF document from the URL using promices
PDFJS.getDocument(pdfWithFormsPath).then(function getPdfForm(pdf) {
// Rendering all pages starting from first
var viewer = document.getElementById('viewer');
var pageNumber = 1;
renderPage(viewer, pdf, pageNumber++, function pageRenderingComplete() {
if (pageNumber > pdf.numPages) {
return; // All pages rendered
}
// Continue rendering of the next page
renderPage(viewer, pdf, pageNumber++, pageRenderingComplete);
});
});

View File

@ -0,0 +1,41 @@
<!doctype html>
<html>
<head>
<!-- In production, only one script (pdf.js) is necessary -->
<!-- In production, change the content of PDFJS.workerSrc below -->
<script src="../../src/shared/util.js"></script>
<script src="../../src/display/api.js"></script>
<script src="../../src/display/metadata.js"></script>
<script src="../../src/display/canvas.js"></script>
<script src="../../src/display/webgl.js"></script>
<script src="../../src/display/pattern_helper.js"></script>
<script src="../../src/display/font_loader.js"></script>
<script src="../../src/display/annotation_helper.js"></script>
<script>
// Specify the main script used to create a new PDF.JS web worker.
// In production, change this to point to the combined `pdf.js` file.
PDFJS.workerSrc = '../../src/worker_loader.js';
// Specify the PDF with AcroForm here
var pdfWithFormsPath = '../../test/pdfs/f1040.pdf';
</script>
<style>
.pdfpage { position:relative; top: 0; left: 0; border: solid 1px black; margin: 10px; }
.pdfpage > canvas { position: absolute; top: 0; left: 0; }
.pdfpage > div { position: absolute; top: 0; left: 0; }
.inputControl { background: transparent; border: 0px none; position: absolute; margin: auto; }
.inputControl[type='checkbox'] { margin: 0px; }
.inputHint { opacity: 0.2; background: #ccc; position: absolute; }
</style>
<script src="forms.js"></script>
</head>
<body>
<div id="viewer"></div>
</body>
</html>

View File

@ -1,43 +0,0 @@
<!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

@ -1,63 +0,0 @@
/* 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

@ -14,7 +14,7 @@ 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>
<html dir="ltr" mozdisallowselectionprint moznomarginboxes>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
@ -27,18 +27,14 @@ limitations under the License.
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">
<link rel="stylesheet" href="../../build/components/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>
<!-- for legacy browsers -->
<script src="../../build/components/compatibility.js"></script>
<script src="../../build/pdf.js"></script>
<script src="../../build/components/pdf_viewer.js"></script>
</head>
<body tabindex="1">
@ -46,6 +42,7 @@ limitations under the License.
<div id="viewer" class="pdfViewer"></div>
</div>
<script src="simpleviewer.mjs" type="module"></script>
<script src="simpleviewer.js"></script>
</body>
</html>

View File

@ -0,0 +1,50 @@
/* 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.
*/
'use strict';
if (!PDFJS.PDFViewer || !PDFJS.getDocument) {
alert('Please build the library and components using\n' +
' `node make generic components`');
}
// 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.
//
// PDFJS.workerSrc = '../../build/pdf.worker.js';
// Some PDFs need external cmaps.
//
// PDFJS.cMapUrl = '../../external/bcmaps/';
// PDFJS.cMapPacked = true;
var DEFAULT_URL = '../../web/compressed.tracemonkey-pldi-09.pdf';
var container = document.getElementById('viewerContainer');
var pdfViewer = new PDFJS.PDFViewer({
container: container
});
container.addEventListener('pagesinit', function () {
// we can use pdfViewer now, e.g. let's change default scale.
pdfViewer.currentScaleValue = 'page-width';
});
// Loading document.
PDFJS.getDocument(DEFAULT_URL).then(function (pdfDocument) {
// Document loaded, specifying document for the viewer.
pdfViewer.setDocument(pdfDocument);
});

View File

@ -1,97 +0,0 @@
/* 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

@ -1,51 +0,0 @@
<!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

@ -1,97 +0,0 @@
/* 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);

View File

@ -0,0 +1,18 @@
## "Hello World" overview
This example is a minimalistic application of the pdf.js project. The file
`helloworld.pdf` is from the GNUpdf project (see [Introduction to PDF at
GNUpdf] (http://gnupdf.org/Introduction_to_PDF)), and contains a simple and
human-readable PDF.
## Getting started
Point your browser to `index.html`. Voila. Take a peek at `hello.js` to see
how to make basic calls to `pdf.js`.
## Additional resources
+ [GNUpdf - Introduction to PDF](http://gnupdf.org/Introduction_to_PDF)

View File

@ -0,0 +1,37 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
//
// See README for overview
//
'use strict';
//
// Fetch the PDF document from the URL using promises
//
PDFJS.getDocument('helloworld.pdf').then(function(pdf) {
// Using promise to fetch the page
pdf.getPage(1).then(function(page) {
var scale = 1.5;
var viewport = page.getViewport(scale);
//
// Prepare canvas using PDF page dimensions
//
var canvas = document.getElementById('the-canvas');
var context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
//
// Render PDF page into canvas context
//
var renderContext = {
canvasContext: context,
viewport: viewport
};
page.render(renderContext);
});
});

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,29 @@
<!doctype html>
<html>
<head>
<!-- In production, only one script (pdf.js) is necessary -->
<!-- In production, change the content of PDFJS.workerSrc below -->
<script src="../../src/shared/util.js"></script>
<script src="../../src/display/api.js"></script>
<script src="../../src/display/metadata.js"></script>
<script src="../../src/display/canvas.js"></script>
<script src="../../src/display/webgl.js"></script>
<script src="../../src/display/pattern_helper.js"></script>
<script src="../../src/display/font_loader.js"></script>
<script src="../../src/display/annotation_helper.js"></script>
<script>
// Specify the main script used to create a new PDF.JS web worker.
// In production, leave this undefined or change it to point to the
// combined `pdf.worker.js` file.
PDFJS.workerSrc = '../../src/worker_loader.js';
</script>
<script src="hello.js"></script>
</head>
<body>
<canvas id="the-canvas" style="border:1px solid black;"/>
</body>
</html>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

View File

@ -1,40 +0,0 @@
<!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

@ -1,59 +0,0 @@
/* 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

@ -8,61 +8,63 @@
<h1>'Hello, world!' example</h1>
<canvas id="the-canvas" style="border: 1px solid black; direction: ltr;"></canvas>
<canvas id="the-canvas" style="border:1px solid black"></canvas>
<script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script>
<!-- for legacy browsers add compatibility.js -->
<!--<script src="../compatibility.js"></script>-->
<script id="script" type="module">
<script src="../../build/pdf.js"></script>
<script id="script">
//
// If absolute URL from the remote server is provided, configure the CORS
// header on that server.
//
const url = './helloworld.pdf';
var url = './helloworld.pdf';
//
// The workerSrc property shall be specified.
// Disable workers to avoid yet another cross-origin issue (workers need
// the URL of the script to be loaded, and dynamically loading a cross-origin
// script does not work).
//
pdfjsLib.GlobalWorkerOptions.workerSrc =
'../../node_modules/pdfjs-dist/build/pdf.worker.mjs';
// PDFJS.disableWorker = true;
//
// 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.
//
// PDFJS.workerSrc = '../../build/pdf.worker.js';
//
// 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;
PDFJS.getDocument(url).then(function getPdfHelloWorld(pdf) {
//
// Fetch the first page
//
pdf.getPage(1).then(function getPageHelloWorld(page) {
var scale = 1.5;
var viewport = page.getViewport(scale);
//
// Prepare canvas using PDF page dimensions
//
const canvas = document.getElementById("the-canvas");
const context = canvas.getContext("2d");
//
// Prepare canvas using PDF page dimensions
//
var canvas = document.getElementById('the-canvas');
var context = canvas.getContext('2d');
canvas.height = viewport.height;
canvas.width = viewport.width;
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);
//
// Render PDF page into canvas context
//
var renderContext = {
canvasContext: context,
viewport: viewport
};
page.render(renderContext);
});
});
</script>
<hr>

View File

@ -1,81 +0,0 @@
<!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

@ -16,25 +16,35 @@
</div>
<div>
<canvas id="the-canvas" style="border: 1px solid black; direction: ltr;"></canvas>
<canvas id="the-canvas" style="border:1px solid black"></canvas>
</div>
<script src="../../node_modules/pdfjs-dist/build/pdf.mjs" type="module"></script>
<!-- for legacy browsers add compatibility.js -->
<!--<script src="../compatibility.js"></script>-->
<script id="script" type="module">
<script src="../../build/pdf.js"></script>
<script id="script">
//
// If absolute URL from the remote server is provided, configure the CORS
// header on that server.
//
var url = '../../web/compressed.tracemonkey-pldi-09.pdf';
//
// Disable workers to avoid yet another cross-origin issue (workers need
// the URL of the script to be loaded, and dynamically loading a cross-origin
// script does not work).
//
// PDFJS.disableWorker = true;
//
// 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
// 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';
// PDFJS.workerSrc = '../../build/pdf.worker.js';
var pdfDoc = null,
pageNum = 1,
@ -52,24 +62,14 @@
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;
var viewport = page.getViewport(scale);
canvas.height = viewport.height;
canvas.width = viewport.width;
// Render PDF page into canvas context
var renderContext = {
canvasContext: ctx,
transform: transform,
viewport: viewport,
viewport: viewport
};
var renderTask = page.render(renderContext);
@ -85,12 +85,12 @@
});
// Update page counters
document.getElementById('page_num').textContent = num;
document.getElementById('page_num').textContent = pageNum;
}
/**
* If another page rendering in progress, waits until the rendering is
* finished. Otherwise, executes rendering immediately.
* finised. Otherwise, executes rendering immediately.
*/
function queueRenderPage(num) {
if (pageRendering) {
@ -127,12 +127,13 @@
/**
* Asynchronously downloads PDF.
*/
var loadingTask = pdfjsLib.getDocument(url);
pdfDoc = await loadingTask.promise;
document.getElementById('page_count').textContent = pdfDoc.numPages;
PDFJS.getDocument(url).then(function (pdfDoc_) {
pdfDoc = pdfDoc_;
document.getElementById('page_count').textContent = pdfDoc.numPages;
// Initial/first page rendering
renderPage(pageNum);
// Initial/first page rendering
renderPage(pageNum);
});
</script>
</body>

View File

@ -1,11 +0,0 @@
## 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.

Before

Width:  |  Height:  |  Size: 169 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 185 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 295 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 166 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 184 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 295 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 560 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 310 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 338 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 372 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 395 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

View File

@ -1,57 +0,0 @@
<!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"></button>
<button class="toolbarButton pageDown" title="Next Page" id="next"></button>
<input type="number" id="pageNumber" class="toolbarField pageNumber" value="1" size="4" min="1">
<button class="toolbarButton zoomOut" title="Zoom Out" id="zoomOut"></button>
<button class="toolbarButton zoomIn" title="Zoom In" id="zoomIn"></button>
</footer>
<script src="viewer.mjs" type="module"></script>
</body>
</html>

View File

@ -1,371 +0,0 @@
/* 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.MissingPDFException) {
key = "pdfjs-missing-file-error";
} else if (reason instanceof pdfjsLib.UnexpectedResponseException) {
key = "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,
});
});

View File

@ -1,9 +0,0 @@
{
"extends": [
"../.eslintrc"
],
"env": {
"node": true,
},
}

View File

@ -0,0 +1,107 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
// Dummy XML Parser
function DOMNodeMock(nodeName, nodeValue) {
this.nodeName = nodeName;
this.nodeValue = nodeValue;
Object.defineProperty(this, 'parentNode', {value: null, writable: true});
}
DOMNodeMock.prototype = {
get firstChild() {
return this.childNodes[0];
},
get nextSibling() {
var index = this.parentNode.childNodes.indexOf(this);
return this.parentNode.childNodes[index + 1];
},
get textContent() {
if (!this.childNodes) {
return this.nodeValue || '';
}
return this.childNodes.map(function (child) {
return child.textContent;
}).join('');
},
hasChildNodes: function () {
return this.childNodes && this.childNodes.length > 0;
}
};
function decodeXML(text) {
if (text.indexOf('&') < 0) {
return text;
}
return text.replace(/&(#(x[0-9a-f]+|\d+)|\w+);/gi, function (all, entityName, number) {
if (number) {
return String.fromCharCode(number[0] === 'x' ? parseInt(number.substring(1), 16) : +number);
}
switch (entityName) {
case 'amp':
return '&';
case 'lt':
return '<';
case 'gt':
return '>';
case 'quot':
return '\"';
case 'apos':
return '\'';
}
return '&' + entityName + ';';
});
}
function DOMParserMock() {};
DOMParserMock.prototype = {
parseFromString: function (content) {
content = content.replace(/<\?[\s\S]*?\?>|<!--[\s\S]*?-->/g, '').trim();
var nodes = [];
content = content.replace(/>([\s\S]+?)</g, function (all, text) {
var i = nodes.length;
var node = new DOMNodeMock('#text', decodeXML(text));
nodes.push(node);
if (node.textContent.trim().length === 0) {
return '><'; // ignoring whitespaces
}
return '>' + i + ',<';
});
content = content.replace(/<!\[CDATA\[([\s\S]*?)\]\]>/g, function (all, text) {
var i = nodes.length;
var node = new DOMNodeMock('#text', text);
nodes.push(node);
return i + ',';
});
var lastLength;
do {
lastLength = nodes.length;
content = content.replace(/<([\w\:]+)((?:[\s\w:=]|'[^']*'|"[^"]*")*)(?:\/>|>([\d,]*)<\/[^>]+>)/g,
function (all, name, attrs, content) {
var i = nodes.length;
var node = new DOMNodeMock(name);
var children = [];
if (content) {
content = content.split(',');
content.pop();
content.forEach(function (child) {
var childNode = nodes[+child];
childNode.parentNode = node;
children.push(childNode);
})
}
node.childNodes = children;
nodes.push(node);
return i + ',';
});
} while(lastLength < nodes.length);
return {
documentElement: nodes.pop()
};
}
};
exports.DOMParserMock = DOMParserMock;

141
examples/node/domstubs.js Normal file
View File

@ -0,0 +1,141 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
var sheet = {
cssRules: [],
insertRule: function(rule) {
this.cssRules.push(rule);
},
};
var style = {
sheet: sheet,
};
function xmlEncode(s){
var i = 0, ch;
s = String(s);
while (i < s.length && (ch = s[i]) !== '&' && ch !== '<' &&
ch !== '\"' && ch !== '\n' && ch !== '\r' && ch !== '\t') {
i++;
}
if (i >= s.length) {
return s;
}
var buf = s.substring(0, i);
while (i < s.length) {
ch = s[i++];
switch (ch) {
case '&':
buf += '&amp;';
break;
case '<':
buf += '&lt;';
break;
case '\"':
buf += '&quot;';
break;
case '\n':
buf += '&#xA;';
break;
case '\r':
buf += '&#xD;';
break;
case '\t':
buf += '&#x9;';
break;
default:
buf += ch;
break;
}
}
return buf;
}
global.btoa = function btoa(chars) {
var digits =
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
var buffer = '';
var i, n;
for (i = 0, n = chars.length; i < n; i += 3) {
var b1 = chars.charCodeAt(i) & 0xFF;
var b2 = chars.charCodeAt(i + 1) & 0xFF;
var b3 = chars.charCodeAt(i + 2) & 0xFF;
var d1 = b1 >> 2, d2 = ((b1 & 3) << 4) | (b2 >> 4);
var d3 = i + 1 < n ? ((b2 & 0xF) << 2) | (b3 >> 6) : 64;
var d4 = i + 2 < n ? (b3 & 0x3F) : 64;
buffer += (digits.charAt(d1) + digits.charAt(d2) +
digits.charAt(d3) + digits.charAt(d4));
}
return buffer;
};
function DOMElement(name) {
this.nodeName = name;
this.childNodes = [];
this.attributes = {};
this.textContent = '';
}
DOMElement.prototype = {
setAttributeNS: function DOMElement_setAttributeNS(NS, name, value) {
value = value || '';
value = xmlEncode(value);
this.attributes[name] = value;
},
appendChild: function DOMElement_appendChild(element) {
var childNodes = this.childNodes;
if (childNodes.indexOf(element) === -1) {
childNodes.push(element);
}
},
toString: function DOMElement_toString() {
var attrList = [];
for (i in this.attributes) {
attrList.push(i + '="' + xmlEncode(this.attributes[i]) + '"');
}
if (this.nodeName === 'svg:tspan' || this.nodeName === 'svg:style') {
var encText = xmlEncode(this.textContent);
return '<' + this.nodeName + ' ' + attrList.join(' ') + '>' +
encText + '</' + this.nodeName + '>';
} else if (this.nodeName === 'svg:svg') {
var ns = 'xmlns:xlink="http://www.w3.org/1999/xlink" ' +
'xmlns:svg="http://www.w3.org/2000/svg"'
return '<' + this.nodeName + ' ' + ns + ' ' + attrList.join(' ') + '>' +
this.childNodes.join('') + '</' + this.nodeName + '>';
} else {
return '<' + this.nodeName + ' ' + attrList.join(' ') + '>' +
this.childNodes.join('') + '</' + this.nodeName + '>';
}
},
cloneNode: function DOMElement_cloneNode() {
var newNode = new DOMElement(this.nodeName);
newNode.childNodes = this.childNodes;
newNode.attributes = this.attributes;
newNode.textContent = this.textContent;
return newNode;
},
}
global.document = {
childNodes : [],
getElementById: function (id) {
if (id === 'PDFJS_FONT_STYLE_TAG') {
return style;
}
},
createElementNS: function (NS, element) {
var elObject = new DOMElement(element);
return elObject;
},
};

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

@ -0,0 +1,76 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* 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.
// Requires single file built version of PDF.js -- please run
// `node make singlefile` before running the example.
//
var fs = require('fs');
// HACK few hacks to let PDF.js be loaded not as a module in global space.
global.window = global;
global.navigator = { userAgent: "node" };
global.PDFJS = {};
global.DOMParser = require('./domparsermock.js').DOMParserMock;
require('../../build/singlefile/build/pdf.combined.js');
// Loading file from file system into typed array
var pdfPath = process.argv[2] || '../../web/compressed.tracemonkey-pldi-09.pdf';
var data = new Uint8Array(fs.readFileSync(pdfPath));
// Will be using promises to load document, pages and misc data instead of
// callback.
PDFJS.getDocument(data).then(function (doc) {
var numPages = doc.numPages;
console.log('# Document Loaded');
console.log('Number of Pages: ' + numPages);
console.log();
var 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.metadata, null, 2));
console.log();
}
});
var loadPage = function (pageNum) {
return doc.getPage(pageNum).then(function (page) {
console.log('# Page ' + pageNum);
var viewport = page.getViewport(1.0 /* scale */);
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
var strings = content.items.map(function (item) {
return item.str;
});
console.log('## Text Content');
console.log(strings.join(' '));
}).then(function () {
console.log();
});
})
};
// Loading of the first page will wait on metadata and subsequent loadings
// will wait on the previous pages.
for (var 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

@ -1,76 +0,0 @@
/* 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

@ -1,17 +0,0 @@
## 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
Install the Node canvas library and run the example to convert the first page of a
PDF file to a PNG image:
$ npm install canvas
$ cd examples/node/pdf2png
$ node pdf2png.js

View File

@ -1,106 +0,0 @@
/* 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 { strict as assert } from "assert";
import Canvas from "canvas";
import fs from "fs";
import { getDocument } from "pdfjs-dist/legacy/build/pdf.mjs";
class NodeCanvasFactory {
create(width, height) {
assert(width > 0 && height > 0, "Invalid canvas size");
const canvas = Canvas.createCanvas(width, height);
const context = canvas.getContext("2d");
return {
canvas,
context,
};
}
reset(canvasAndContext, width, height) {
assert(canvasAndContext.canvas, "Canvas is not specified");
assert(width > 0 && height > 0, "Invalid canvas size");
canvasAndContext.canvas.width = width;
canvasAndContext.canvas.height = height;
}
destroy(canvasAndContext) {
assert(canvasAndContext.canvas, "Canvas is not specified");
// Zeroing the width and height cause Firefox to release graphics
// resources immediately, which can greatly reduce memory consumption.
canvasAndContext.canvas.width = 0;
canvasAndContext.canvas.height = 0;
canvasAndContext.canvas = null;
canvasAndContext.context = null;
}
}
// 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/";
const canvasFactory = new NodeCanvasFactory();
// 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,
canvasFactory,
});
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 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();
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);
}

87
examples/node/pdf2svg.js Normal file
View File

@ -0,0 +1,87 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
//
// Node tool to dump SVG output into a file.
//
var fs = require('fs');
// HACK few hacks to let PDF.js be loaded not as a module in global space.
global.window = global;
global.navigator = { userAgent: 'node' };
global.PDFJS = {};
require('./domstubs.js');
PDFJS.workerSrc = true;
require('../../build/singlefile/build/pdf.combined.js');
// Loading file from file system into typed array
var pdfPath = process.argv[2] || '../../web/compressed.tracemonkey-pldi-09.pdf';
var data = new Uint8Array(fs.readFileSync(pdfPath));
// Dumps svg outputs to a folder called svgdump
function writeToFile(svgdump, pageNum) {
var name = getFileNameFromPath(pdfPath);
fs.mkdir('./svgdump/', function(err) {
if (!err || err.code === 'EEXIST') {
fs.writeFile('./svgdump/' + name + "-" + pageNum + '.svg', svgdump,
function(err) {
if (err) {
console.log('Error: ' + err);
} else {
console.log('Page: ' + pageNum);
}
});
}
});
}
// Get filename from the path
function getFileNameFromPath(path) {
var index = path.lastIndexOf('/');
var extIndex = path.lastIndexOf('.');
return path.substring(index , extIndex);
}
// Will be using promises to load document, pages and misc data instead of
// callback.
PDFJS.getDocument(data).then(function (doc) {
var numPages = doc.numPages;
console.log('# Document Loaded');
console.log('Number of Pages: ' + numPages);
console.log();
var lastPromise = Promise.resolve(); // will be used to chain promises
var loadPage = function (pageNum) {
return doc.getPage(pageNum).then(function (page) {
console.log('# Page ' + pageNum);
var viewport = page.getViewport(1.0 /* scale */);
console.log('Size: ' + viewport.width + 'x' + viewport.height);
console.log();
return page.getOperatorList().then(function (opList) {
var svgGfx = new PDFJS.SVGGraphics(page.commonObjs, page.objs);
svgGfx.embedFonts = true;
return svgGfx.getSVG(opList, viewport).then(function (svg) {
var svgDump = svg.toString();
writeToFile(svgDump, pageNum);
});
});
})
};
for (var 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,8 @@
## PDF.js using SVG
This is a project for implementing alternate backend for PDF.js using Scalable Vector Graphics. This is still a WIP.
Take a look at [proposal](https://docs.google.com/document/d/1k4nPx1RrHbxXi94kSdvW5ay8KMkjwLmBEiCNupyzlwk/pub) for this project.
## Getting started
Take a look at src/display/svg.js to see the SVG rendering code.

View File

@ -0,0 +1,39 @@
<!DOCTYPE html>
<html>
<head>
<!-- In production, only one script (pdf.js) is necessary -->
<!-- In production, change the content of PDFJS.workerSrc below -->
<script src="../../src/shared/util.js"></script>
<script src="../../src/display/api.js"></script>
<script src="../../src/display/metadata.js"></script>
<script src="../../src/display/pattern_helper.js"></script>
<script src="../../src/display/font_loader.js"></script>
<script src="../../src/display/svg.js"></script>
<script>
// Specify the main script used to create a new PDF.JS web worker.
// In production, leave this undefined or change it to point to the
// combined `pdf.worker.js` file.
PDFJS.workerSrc = '../../src/worker_loader.js';
</script>
<script src="viewer.js"></script>
<style>
body {
background-color: gray;
}
.pageContainer {
border : 1px solid black;
margin : 5px auto;
background-color : white;
}
</style>
<title>SVG Viewer Example</title>
</head>
<body>
</body>
</html>

View File

@ -0,0 +1,59 @@
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
//
// See README for overview
//
'use strict';
// Parse query string to extract some parameters (it can fail for some input)
var query = document.location.href.replace(/^[^?]*(\?([^#]*))?(#.*)?/, '$2');
var queryParams = query ? JSON.parse('{' + query.split('&').map(function (a) {
return a.split('=').map(decodeURIComponent).map(JSON.stringify).join(': ');
}).join(',') + '}') : {};
var url = queryParams.file || '../../test/pdfs/liveprogramming.pdf';
var scale = +queryParams.scale || 1.5;
//
// Fetch the PDF document from the URL using promises
//
PDFJS.getDocument(url).then(function(pdf) {
var numPages = pdf.numPages;
// Using promise to fetch the page
// For testing only.
var MAX_NUM_PAGES = 50;
var ii = Math.min(MAX_NUM_PAGES, numPages);
var promise = Promise.resolve();
for (var i = 1; i <= ii; i++) {
var anchor = document.createElement('a');
anchor.setAttribute('name', 'page=' + i);
anchor.setAttribute('title', 'Page ' + i);
document.body.appendChild(anchor);
// Using promise to fetch and render the next page
promise = promise.then(function (pageNum, anchor) {
return pdf.getPage(pageNum).then(function (page) {
var viewport = page.getViewport(scale);
var container = document.createElement('div');
container.id = 'pageContainer' + pageNum;
container.className = 'pageContainer';
container.style.width = viewport.width + 'px';
container.style.height = viewport.height + 'px';
anchor.appendChild(container);
return page.getOperatorList().then(function (opList) {
var svgGfx = new PDFJS.SVGGraphics(page.commonObjs, page.objs);
return svgGfx.getSVG(opList, viewport).then(function (svg) {
container.appendChild(svg);
});
});
});
}.bind(null, i, anchor));
}
});

View File

@ -1,10 +1,9 @@
<!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>
<script src="../../build/generic/build/pdf.js"></script>
<script src="pdf2svg.js"></script>
</head>
<body>
<p>Text-only PDF.js example</p>

View File

@ -0,0 +1,68 @@
/* 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.
*/
var PDF_PATH = '../../web/compressed.tracemonkey-pldi-09.pdf';
var PAGE_NUMBER = 1;
var PAGE_SCALE = 1.5;
var SVG_NS = 'http://www.w3.org/2000/svg';
function buildSVG(viewport, textContent) {
// Building SVG with size of the viewport (for simplicity)
var 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 incudes scale,
// rotation and Y-axis flip, and not forgetting to flip text.
var tx = PDFJS.Util.transform(
PDFJS.Util.transform(viewport.transform, textItem.transform),
[1, 0, 0, -1, 0, 0]);
var style = textContent.styles[textItem.fontName];
// adding text element
var text = document.createElementNS(SVG_NS, 'svg:text');
text.setAttribute('transform', 'matrix(' + tx.join(' ') + ')');
text.setAttribute('font-family', style.fontFamily);
text.textContent = textItem.str;
svg.appendChild(text);
});
return svg;
}
function pageLoaded() {
// Loading document and page text content
PDFJS.getDocument({url: PDF_PATH}).then(function (pdfDocument) {
pdfDocument.getPage(PAGE_NUMBER).then(function (page) {
var viewport = page.getViewport(PAGE_SCALE);
page.getTextContent().then(function (textContent) {
// building SVG and adding that to the DOM
var svg = buildSVG(viewport, textContent);
document.getElementById('pageContainer').appendChild(svg);
});
});
});
}
document.addEventListener('DOMContentLoaded', function () {
if (typeof PDFJS === 'undefined') {
alert('Built version of PDF.js was not found.\n' +
'Please run `node make generic`.');
return;
}
pageLoaded();
});

View File

@ -1,72 +0,0 @@
/* 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();
});

View File

@ -0,0 +1,43 @@
body {
font-family: arial, verdana, sans-serif;
}
/* Allow absolute positioning of the canvas and textLayer in the page. They
will be the same size and will be placed on top of each other. */
.pdfPage {
position: relative;
overflow: visible;
border: 1px solid #000000;
}
.pdfPage > canvas {
position: absolute;
top: 0;
left: 0;
}
/* CSS classes used by TextLayerBuilder to style the text layer divs */
/* This stuff is important! Otherwise when you select the text,
the text in the divs will show up! */
::selection { background:rgba(0,0,255,0.3); }
::-moz-selection { background:rgba(0,0,255,0.3); }
.textLayer {
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
color: #000;
font-family: sans-serif;
overflow: hidden;
}
.textLayer > div {
color: transparent;
position: absolute;
line-height: 1;
white-space: pre;
cursor: text;
}

View File

@ -0,0 +1,26 @@
<html>
<head>
<title>Minimal pdf.js text-selection demo</title>
<link href="css/minimal.css" rel="stylesheet" media="screen" />
<!-- you will need to run "node make generic" first before you can use this -->
<script src="../../build/generic/build/pdf.js"></script>
<!-- These files are viewer components that you will need to get text-selection to work -->
<script src="../../web/ui_utils.js"></script>
<script src="../../web/text_layer_builder.js"></script>
<script>
// Specify the main script used to create a new PDF.JS web worker.
// In production, change this to point to the combined `pdf.js` file.
</script>
<script src="js/minimal.js"></script>
</head>
<body>
This is a minimal pdf.js text-selection demo. The existing minimal-example shows you how to render a PDF, but not
how to enable text-selection. This example shows you how to do both. <br /><br />
<div id="pdfContainer">
</div>
</body>
</html>

View File

@ -0,0 +1,97 @@
// Minimal PDF rendering and text-selection example using PDF.js by Vivin Suresh Paliath (http://vivin.net)
// This example uses a built version of PDF.js that contains all modules that it requires.
//
// The problem with understanding text selection was that the text selection code has heavily intertwined
// with viewer.html and viewer.js. I have extracted the parts I need out of viewer.js into a separate file
// which contains the bare minimum required to implement text selection. The key component is TextLayerBuilder,
// which is the object that handles the creation of text-selection divs. I have added this code as an external
// resource.
//
// This demo uses a PDF that only has one page. You can render other pages if you wish, but the focus here is
// just to show you how you can render a PDF with text selection. Hence the code only loads up one page.
//
// The CSS used here is also very important since it sets up the CSS for the text layer divs overlays that
// you actually end up selecting.
//
// NOTE: The original example was changed to remove jQuery usage, re-structure and add more comments.
window.onload = function () {
if (typeof PDFJS === 'undefined') {
alert('Built version of pdf.js is not found\nPlease run `node make generic`');
return;
}
var scale = 1.5; //Set this to whatever you want. This is basically the "zoom" factor for the PDF.
PDFJS.workerSrc = '../../build/generic/build/pdf.worker.js';
function loadPdf(pdfPath) {
var pdf = PDFJS.getDocument(pdfPath);
return pdf.then(renderPdf);
}
function renderPdf(pdf) {
return pdf.getPage(1).then(renderPage);
}
function renderPage(page) {
var viewport = page.getViewport(scale);
// Create and append the 'pdf-page' div to the pdf container.
var pdfPage = document.createElement('div');
pdfPage.className = 'pdfPage';
var pdfContainer = document.getElementById('pdfContainer');
pdfContainer.appendChild(pdfPage);
// Set the canvas height and width to the height and width of the viewport.
var canvas = document.createElement('canvas');
var context = canvas.getContext('2d');
// The following few lines of code set up scaling on the context, if we are
// on a HiDPI display.
var outputScale = getOutputScale(context);
canvas.width = (Math.floor(viewport.width) * outputScale.sx) | 0;
canvas.height = (Math.floor(viewport.height) * outputScale.sy) | 0;
context._scaleX = outputScale.sx;
context._scaleY = outputScale.sy;
if (outputScale.scaled) {
context.scale(outputScale.sx, outputScale.sy);
}
// The page, canvas and text layer elements will have the same size.
canvas.style.width = Math.floor(viewport.width) + 'px';
canvas.style.height = Math.floor(viewport.height) + 'px';
pdfPage.style.width = canvas.style.width;
pdfPage.style.height = canvas.style.height;
pdfPage.appendChild(canvas);
var textLayerDiv = document.createElement('div');
textLayerDiv.className = 'textLayer';
textLayerDiv.style.width = canvas.style.width;
textLayerDiv.style.height = canvas.style.height;
pdfPage.appendChild(textLayerDiv);
// Painting the canvas...
var renderContext = {
canvasContext: context,
viewport: viewport
};
var renderTask = page.render(renderContext);
// ... and at the same time, getting the text and creating the text layer.
var textLayerPromise = page.getTextContent().then(function (textContent) {
var textLayerBuilder = new TextLayerBuilder({
textLayerDiv: textLayerDiv,
viewport: viewport,
pageIndex: 0
});
textLayerBuilder.setTextContent(textContent);
});
// We might be interested when rendering complete and text layer is built.
return Promise.all([renderTask.promise, textLayerPromise]);
}
loadPdf('pdf/TestDocument.pdf');
};

Binary file not shown.

View File

@ -1,9 +0,0 @@
{
"extends": [
"../.eslintrc"
],
"env": {
"node": true,
},
}

View File

@ -1 +0,0 @@
node_modules/

View File

@ -1,33 +0,0 @@
## 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';

Some files were not shown because too many files have changed in this diff Show More