fix merge conflicts
This commit is contained in:
commit
ff2dea38ec
7
Makefile
7
Makefile
@ -88,7 +88,8 @@ browser-test:
|
||||
# To install gjslint, see:
|
||||
#
|
||||
# <http://code.google.com/closure/utilities/docs/linter_howto.html>
|
||||
SRC_DIRS := . utils worker web test
|
||||
SRC_DIRS := . utils worker web test examples/helloworld extensions/firefox \
|
||||
extensions/firefox/components
|
||||
GJSLINT_FILES = $(foreach DIR,$(SRC_DIRS),$(wildcard $(DIR)/*.js))
|
||||
lint:
|
||||
gjslint $(GJSLINT_FILES)
|
||||
@ -165,9 +166,9 @@ PDF_WEB_FILES = \
|
||||
extension:
|
||||
# Copy a standalone version of pdf.js inside the content directory
|
||||
@rm -Rf $(EXTENSION_SRC)/$(CONTENT_DIR)/
|
||||
@mkdir $(EXTENSION_SRC)/$(CONTENT_DIR)/
|
||||
@mkdir -p $(EXTENSION_SRC)/$(CONTENT_DIR)/web
|
||||
@cp $(PDF_JS_FILES) $(EXTENSION_SRC)/$(CONTENT_DIR)/
|
||||
@cp -r $(PDF_WEB_FILES) $(EXTENSION_SRC)/$(CONTENT_DIR)/
|
||||
@cp -r $(PDF_WEB_FILES) $(EXTENSION_SRC)/$(CONTENT_DIR)/web/
|
||||
|
||||
# Create the xpi
|
||||
@cd $(EXTENSION_SRC); zip -r $(EXTENSION_NAME) *
|
||||
|
89
README.md
89
README.md
@ -18,46 +18,42 @@ successful.
|
||||
|
||||
## Getting started
|
||||
|
||||
**Online demo**
|
||||
### Online demo
|
||||
|
||||
For an online demo, visit:
|
||||
|
||||
http://andreasgal.github.com/pdf.js/web/viewer.html
|
||||
+ http://andreasgal.github.com/pdf.js/web/viewer.html
|
||||
|
||||
This demo provides an interactive interface for displaying and browsing PDFs
|
||||
using the pdf.js API.
|
||||
|
||||
**Getting the code**
|
||||
### Getting the code
|
||||
|
||||
To get a local copy of the current code, clone it using git:
|
||||
|
||||
```bash
|
||||
git clone git://github.com/andreasgal/pdf.js.git pdfjs
|
||||
cd pdfjs
|
||||
```
|
||||
$ git clone git://github.com/andreasgal/pdf.js.git pdfjs
|
||||
$ cd pdfjs
|
||||
|
||||
Next, you need to start a local web server as some browsers don't allow opening
|
||||
PDF files for a file:// url:
|
||||
|
||||
```bash
|
||||
make server
|
||||
```
|
||||
$ make server
|
||||
|
||||
If everything worked out, you can now serve
|
||||
|
||||
http://localhost:8888/web/viewer.html
|
||||
+ http://localhost:8888/web/viewer.html
|
||||
|
||||
You can also view all the test pdf files on the right side serving
|
||||
|
||||
http://localhost:8888/test/pdfs/?frame
|
||||
+ http://localhost:8888/test/pdfs/?frame
|
||||
|
||||
|
||||
|
||||
**Hello world**
|
||||
### Hello world
|
||||
|
||||
For a "hello world" example, take a look at:
|
||||
|
||||
examples/helloworld/
|
||||
+ [examples/helloworld/hello.js](https://github.com/andreasgal/pdf.js/blob/master/examples/helloworld/hello.js)
|
||||
|
||||
This example illustrates the bare minimum ingredients for integrating pdf.js
|
||||
in a custom project.
|
||||
@ -66,16 +62,22 @@ in a custom project.
|
||||
|
||||
## Contributing
|
||||
|
||||
pdf.js is a community-driver project, so contributors are always welcome.
|
||||
pdf.js is a community-driven project, so contributors are always welcome.
|
||||
Simply fork our repo and contribute away. A great place to start is our
|
||||
open issues. For better consistency and long-term stability, please do look around the
|
||||
code and try to follow our conventions.
|
||||
[open issues](https://github.com/andreasgal/pdf.js/issues). For better consistency and
|
||||
long-term stability, please do look around the code and try to follow our conventions.
|
||||
|
||||
If you __don't want to hack__ on the project or have short spare times, you still
|
||||
can help! Just open PDFs in the
|
||||
If you don't want to hack on the project or have short spare times, __you still
|
||||
can help!__ Just open PDFs in the
|
||||
[online demo](http://andreasgal.github.com/pdf.js/web/viewer.html) and report
|
||||
any breakage in rendering.
|
||||
|
||||
Our Github contributors so far:
|
||||
|
||||
+ https://github.com/andreasgal/pdf.js/contributors
|
||||
|
||||
You can add your name to it! :)
|
||||
|
||||
|
||||
|
||||
## Running the Tests
|
||||
@ -108,47 +110,46 @@ raising any errors.
|
||||
|
||||
Our demo site is here:
|
||||
|
||||
http://andreasgal.github.com/pdf.js/web/viewer.html
|
||||
+ http://andreasgal.github.com/pdf.js/web/viewer.html
|
||||
|
||||
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/
|
||||
|
||||
Follow us on twitter: @pdfjs
|
||||
|
||||
http://twitter.com/#!/pdfjs
|
||||
|
||||
Join our mailing list:
|
||||
|
||||
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
|
||||
+ http://andreasgal.com/2011/06/15/pdf-js/
|
||||
+ http://blog.mozilla.com/cjones/2011/06/15/overview-of-pdf-js-guts/
|
||||
|
||||
Talk to us on IRC:
|
||||
|
||||
#pdfjs on irc.mozilla.org
|
||||
+ #pdfjs on irc.mozilla.org
|
||||
|
||||
Join our mailing list:
|
||||
|
||||
+ 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
|
||||
|
||||
|
||||
|
||||
## Additional resources to understand the structure of PDF
|
||||
|
||||
A really basic overview of PDF is described here:
|
||||
|
||||
http://partners.adobe.com/public/developer/en/livecycle/lc_pdf_overview_format.pdf
|
||||
+ http://partners.adobe.com/public/developer/en/livecycle/lc_pdf_overview_format.pdf
|
||||
|
||||
A more detailed file example:
|
||||
|
||||
http://gnupdf.org/Introduction_to_PDF
|
||||
+ http://gnupdf.org/Introduction_to_PDF
|
||||
|
||||
The PDF specification itself is an ISO and not free available. However, there is
|
||||
The PDF specification itself is an ISO and not freely available. However, there is
|
||||
a "PDF Reference" from Adobe:
|
||||
|
||||
http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/pdf_reference_1-7.pdf
|
||||
+ http://wwwimages.adobe.com/www.adobe.com/content/dam/Adobe/en/devnet/pdf/pdfs/pdf_reference_1-7.pdf
|
||||
|
||||
Recommanded chapters to read: "2. Overview", "3.4 File Structure",
|
||||
Recommended chapters to read: "2. Overview", "3.4 File Structure",
|
||||
"4.1 Graphics Objects" that lists the PDF commands.
|
||||
|
||||
|
@ -493,16 +493,16 @@ var CipherTransformFactory = (function cipherTransformFactory() {
|
||||
|
||||
function constructor(dict, fileId, password) {
|
||||
var filter = dict.get('Filter');
|
||||
if (!IsName(filter) || filter.name != 'Standard')
|
||||
if (!isName(filter) || filter.name != 'Standard')
|
||||
error('unknown encryption method');
|
||||
this.dict = dict;
|
||||
var algorithm = dict.get('V');
|
||||
if (!IsInt(algorithm) ||
|
||||
if (!isInt(algorithm) ||
|
||||
(algorithm != 1 && algorithm != 2 && algorithm != 4))
|
||||
error('unsupported encryption algorithm');
|
||||
this.algorithm = algorithm;
|
||||
var keyLength = dict.get('Length') || 40;
|
||||
if (!IsInt(keyLength) ||
|
||||
if (!isInt(keyLength) ||
|
||||
keyLength < 40 || (keyLength % 8) != 0)
|
||||
error('invalid key length');
|
||||
// prepare keys
|
||||
|
@ -1,16 +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
|
||||
`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
|
||||
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)
|
||||
|
||||
|
@ -1,36 +1,17 @@
|
||||
/* -*- 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';
|
||||
|
||||
//
|
||||
// Ajax GET request, for binary files
|
||||
// (like jQuery's $.get(), but supports the binary type ArrayBuffer)
|
||||
//
|
||||
var ajaxGet = function(url, callback){
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', url);
|
||||
xhr.mozResponseType = xhr.responseType = 'arraybuffer';
|
||||
xhr.expected = (document.URL.indexOf('file:') === 0) ? 0 : 200;
|
||||
xhr.onreadystatechange = function() {
|
||||
if (xhr.readyState === 4 && xhr.status === xhr.expected) {
|
||||
var data = (xhr.mozResponseArrayBuffer || xhr.mozResponse ||
|
||||
xhr.responseArrayBuffer || xhr.response);
|
||||
|
||||
callback(data);
|
||||
}
|
||||
};
|
||||
xhr.send(null);
|
||||
}
|
||||
|
||||
//
|
||||
// This is where the fun happens
|
||||
//
|
||||
ajaxGet('helloworld.pdf', function(data){
|
||||
getPdf('helloworld.pdf', function getPdfHelloWorld(data) {
|
||||
//
|
||||
// Instantiate PDFDoc with PDF data
|
||||
//
|
||||
var pdf = new PDFDoc(new Stream(data));
|
||||
var pdf = new PDFDoc(data);
|
||||
var page = pdf.getPage(1);
|
||||
var scale = 1.5;
|
||||
|
||||
@ -40,10 +21,11 @@ ajaxGet('helloworld.pdf', function(data){
|
||||
var canvas = document.getElementById('the-canvas');
|
||||
var context = canvas.getContext('2d');
|
||||
canvas.height = page.height * scale;
|
||||
canvas.width = page.width * scale;
|
||||
canvas.width = page.width * scale;
|
||||
|
||||
//
|
||||
// Render PDF page into canvas context
|
||||
//
|
||||
page.startRendering(context);
|
||||
});
|
||||
|
||||
|
27
extensions/firefox/bootstrap.js
vendored
27
extensions/firefox/bootstrap.js
vendored
@ -1,31 +1,36 @@
|
||||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
|
||||
'use strict';
|
||||
|
||||
let Cc = Components.classes;
|
||||
let Ci = Components.interfaces;
|
||||
let Cm = Components.manager;
|
||||
let Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import('resource://gre/modules/Services.jsm');
|
||||
|
||||
function log(str) {
|
||||
dump(str + "\n");
|
||||
};
|
||||
dump(str + '\n');
|
||||
}
|
||||
|
||||
function startup(aData, aReason) {
|
||||
let manifestPath = "chrome.manifest";
|
||||
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
|
||||
let manifestPath = 'chrome.manifest';
|
||||
let file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsILocalFile);
|
||||
try {
|
||||
file.initWithPath(aData.installPath.path);
|
||||
file.append(manifestPath);
|
||||
Cm.QueryInterface(Ci.nsIComponentRegistrar).autoRegister(file);
|
||||
} catch(e) {
|
||||
} catch (e) {
|
||||
log(e);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function shutdown(aData, aReason) {
|
||||
};
|
||||
}
|
||||
|
||||
function install(aData, aReason) {
|
||||
let url = "chrome://pdf.js/content/web/viewer.html?file=%s";
|
||||
Services.prefs.setCharPref("extensions.pdf.js.url", url);
|
||||
};
|
||||
let url = 'chrome://pdf.js/content/web/viewer.html?file=%s';
|
||||
Services.prefs.setCharPref('extensions.pdf.js.url', url);
|
||||
}
|
||||
|
||||
|
@ -1,52 +1,65 @@
|
||||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
|
||||
'use strict';
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cr = Components.results;
|
||||
const Cu = Components.utils;
|
||||
|
||||
const PDF_CONTENT_TYPE = "application/pdf";
|
||||
const PDF_CONTENT_TYPE = 'application/pdf';
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
// TODO
|
||||
// Add some download progress event
|
||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
Cu.import('resource://gre/modules/Services.jsm');
|
||||
|
||||
function log(aMsg) {
|
||||
let msg = "pdfContentHandler.js: " + (aMsg.join ? aMsg.join("") : aMsg);
|
||||
Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService)
|
||||
let msg = 'pdfContentHandler.js: ' + (aMsg.join ? aMsg.join('') : aMsg);
|
||||
Cc['@mozilla.org/consoleservice;1'].getService(Ci.nsIConsoleService)
|
||||
.logStringMessage(msg);
|
||||
dump(msg + "\n");
|
||||
};
|
||||
dump(msg + '\n');
|
||||
}
|
||||
|
||||
function fireEventTo(aName, aData, aWindow) {
|
||||
let window = aWindow.wrappedJSObject;
|
||||
let evt = window.document.createEvent('CustomEvent');
|
||||
evt.initCustomEvent('pdf' + aName, false, false, aData);
|
||||
window.document.dispatchEvent(evt);
|
||||
}
|
||||
|
||||
function loadDocument(aWindow, aDocumentUrl) {
|
||||
let xhr = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
|
||||
let xhr = Cc['@mozilla.org/xmlextras/xmlhttprequest;1']
|
||||
.createInstance(Ci.nsIXMLHttpRequest);
|
||||
xhr.open("GET", aDocumentUrl);
|
||||
xhr.mozResponseType = xhr.responseType = "arraybuffer";
|
||||
xhr.onreadystatechange = function() {
|
||||
if (xhr.readyState == 4 && xhr.status == 200) {
|
||||
let data = (xhr.mozResponseArrayBuffer || xhr.mozResponse ||
|
||||
xhr.responseArrayBuffer || xhr.response);
|
||||
try {
|
||||
var view = new Uint8Array(data);
|
||||
xhr.onprogress = function updateProgress(evt) {
|
||||
if (evt.lengthComputable)
|
||||
fireEventTo(evt.type, evt.loaded / evt.total, aWindow);
|
||||
};
|
||||
|
||||
// I think accessing aWindow.wrappedJSObject returns a
|
||||
// XPCSafeJSObjectWrapper and so it is safe but mrbkap can confirm that
|
||||
let window = aWindow.wrappedJSObject;
|
||||
var arrayBuffer = new window.ArrayBuffer(data.byteLength);
|
||||
var view2 = new window.Uint8Array(arrayBuffer);
|
||||
view2.set(view);
|
||||
xhr.onerror = function error(evt) {
|
||||
fireEventTo(evt.type, false, aWindow);
|
||||
};
|
||||
|
||||
let evt = window.document.createEvent("CustomEvent");
|
||||
evt.initCustomEvent("pdfloaded", false, false, arrayBuffer);
|
||||
window.document.dispatchEvent(evt);
|
||||
} catch(e) {
|
||||
log("Error - " + e);
|
||||
}
|
||||
xhr.onload = function load(evt) {
|
||||
let data = (xhr.mozResponseArrayBuffer || xhr.mozResponse ||
|
||||
xhr.responseArrayBuffer || xhr.response);
|
||||
try {
|
||||
let view = new Uint8Array(data);
|
||||
|
||||
let window = aWindow.wrappedJSObject;
|
||||
let arrayBuffer = new window.ArrayBuffer(data.byteLength);
|
||||
let view2 = new window.Uint8Array(arrayBuffer);
|
||||
view2.set(view);
|
||||
|
||||
fireEventTo(evt.type, arrayBuffer, aWindow);
|
||||
} catch (e) {
|
||||
log('Error - ' + e);
|
||||
}
|
||||
};
|
||||
|
||||
xhr.open('GET', aDocumentUrl);
|
||||
xhr.responseType = 'arraybuffer';
|
||||
xhr.send(null);
|
||||
};
|
||||
}
|
||||
|
||||
let WebProgressListener = {
|
||||
init: function(aWindow, aUrl) {
|
||||
@ -64,11 +77,12 @@ let WebProgressListener = {
|
||||
.getInterface(Ci.nsIWebProgress);
|
||||
try {
|
||||
webProgress.removeProgressListener(this);
|
||||
} catch(e) {}
|
||||
} catch (e) {}
|
||||
webProgress.addProgressListener(this, flags);
|
||||
},
|
||||
|
||||
onStateChange: function onStateChange(aWebProgress, aRequest, aStateFlags, aStatus) {
|
||||
onStateChange: function onStateChange(aWebProgress, aRequest, aStateFlags,
|
||||
aStatus) {
|
||||
const complete = Ci.nsIWebProgressListener.STATE_IS_WINDOW +
|
||||
Ci.nsIWebProgressListener.STATE_STOP;
|
||||
if ((aStateFlags & complete) == complete && this._locationHasChanged) {
|
||||
@ -77,14 +91,17 @@ let WebProgressListener = {
|
||||
}
|
||||
},
|
||||
|
||||
onProgressChange: function onProgressChange(aWebProgress, aRequest, aCurSelf, aMaxSelf, aCurTotal, aMaxTotal) {
|
||||
onProgressChange: function onProgressChange(aWebProgress, aRequest, aCurSelf,
|
||||
aMaxSelf, aCurTotal, aMaxTotal) {
|
||||
},
|
||||
|
||||
onLocationChange: function onLocationChange(aWebProgress, aRequest, aLocationURI) {
|
||||
onLocationChange: function onLocationChange(aWebProgress, aRequest,
|
||||
aLocationURI) {
|
||||
this._locationHasChanged = true;
|
||||
},
|
||||
|
||||
onStatusChange: function onStatusChange(aWebProgress, aRequest, aStatus, aMessage) {
|
||||
onStatusChange: function onStatusChange(aWebProgress, aRequest, aStatus,
|
||||
aMessage) {
|
||||
},
|
||||
|
||||
onSecurityChange: function onSecurityChange(aWebProgress, aRequest, aState) {
|
||||
@ -127,16 +144,16 @@ pdfContentHandler.prototype = {
|
||||
WebProgressListener.init(window, uri.spec);
|
||||
|
||||
try {
|
||||
let url = Services.prefs.getCharPref("extensions.pdf.js.url");
|
||||
url = url.replace("%s", uri.spec);
|
||||
let url = Services.prefs.getCharPref('extensions.pdf.js.url');
|
||||
url = url.replace('%s', uri.spec);
|
||||
window.location = url;
|
||||
} catch(e) {
|
||||
log("Error - " + e);
|
||||
} catch (e) {
|
||||
log('Error retrieving the pdf.js base url - ' + e);
|
||||
}
|
||||
},
|
||||
|
||||
classID: Components.ID("{2278dfd0-b75c-11e0-8257-1ba3d93c9f1a}"),
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentHandler]),
|
||||
classID: Components.ID('{2278dfd0-b75c-11e0-8257-1ba3d93c9f1a}'),
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentHandler])
|
||||
};
|
||||
|
||||
var NSGetFactory = XPCOMUtils.generateNSGetFactory([pdfContentHandler]);
|
||||
|
@ -12,7 +12,7 @@
|
||||
<Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>6.0</em:minVersion>
|
||||
<em:maxVersion>9.0.*</em:maxVersion>
|
||||
<em:maxVersion>10.0.*</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
<em:bootstrap>true</em:bootstrap>
|
||||
|
8
fonts.js
8
fonts.js
@ -1222,7 +1222,7 @@ var Font = (function Font() {
|
||||
encoding[i] = {
|
||||
unicode: i <= 0x1f || (i >= 127 && i <= 255) ?
|
||||
i + kCmapGlyphOffset : i,
|
||||
width: IsNum(width) ? width : properties.defaultWidth
|
||||
width: isNum(width) ? width : properties.defaultWidth
|
||||
};
|
||||
}
|
||||
} else {
|
||||
@ -2212,7 +2212,7 @@ CFF.prototype = {
|
||||
var cmd = map[command];
|
||||
assert(cmd, 'Unknow command: ' + command);
|
||||
|
||||
if (IsArray(cmd))
|
||||
if (isArray(cmd))
|
||||
charstring.splice(i++, 1, cmd[0], cmd[1]);
|
||||
else
|
||||
charstring[i] = cmd;
|
||||
@ -2338,7 +2338,7 @@ CFF.prototype = {
|
||||
continue;
|
||||
var value = properties.private[field];
|
||||
|
||||
if (IsArray(value)) {
|
||||
if (isArray(value)) {
|
||||
data += self.encodeNumber(value[0]);
|
||||
for (var i = 1; i < value.length; i++)
|
||||
data += self.encodeNumber(value[i] - value[i - 1]);
|
||||
@ -2497,7 +2497,7 @@ var Type2CFF = (function type2CFF() {
|
||||
var width = mapping.width;
|
||||
properties.glyphs[glyph] = properties.encoding[index] = {
|
||||
unicode: code,
|
||||
width: IsNum(width) ? width : defaultWidth
|
||||
width: isNum(width) ? width : defaultWidth
|
||||
};
|
||||
|
||||
charstrings.push({
|
||||
|
@ -73,26 +73,16 @@ function nextTask() {
|
||||
|
||||
log('Loading file "' + task.file + '"\n');
|
||||
|
||||
var r = new XMLHttpRequest();
|
||||
r.open('GET', task.file);
|
||||
r.mozResponseType = r.responseType = 'arraybuffer';
|
||||
r.onreadystatechange = function nextTaskOnreadystatechange() {
|
||||
getPdf(task.file, function nextTaskGetPdf(data) {
|
||||
var failure;
|
||||
if (r.readyState == 4) {
|
||||
var data = r.mozResponseArrayBuffer || r.mozResponse ||
|
||||
r.responseArrayBuffer || r.response;
|
||||
|
||||
try {
|
||||
task.pdfDoc = new PDFDoc(data);
|
||||
} catch (e) {
|
||||
failure = 'load PDF doc : ' + e.toString();
|
||||
}
|
||||
|
||||
task.pageNum = 1;
|
||||
nextPage(task, failure);
|
||||
try {
|
||||
task.pdfDoc = new PDFDoc(data);
|
||||
} catch (e) {
|
||||
failure = 'load PDF doc : ' + e.toString();
|
||||
}
|
||||
};
|
||||
r.send(null);
|
||||
task.pageNum = 1;
|
||||
nextPage(task, failure);
|
||||
});
|
||||
}
|
||||
|
||||
function isLastPage(task) {
|
||||
|
1
test/pdfs/unix01.pdf.link
Normal file
1
test/pdfs/unix01.pdf.link
Normal file
@ -0,0 +1 @@
|
||||
https://docs.rice.edu/confluence/download/attachments/4588376/unix01.pdf?version=1
|
@ -128,6 +128,12 @@
|
||||
"rounds": 1,
|
||||
"type": "eq"
|
||||
},
|
||||
{ "id": "unix01",
|
||||
"file": "pdfs/unix01.pdf",
|
||||
"link": true,
|
||||
"rounds": 1,
|
||||
"type": "eq"
|
||||
},
|
||||
{ "id": "fips197",
|
||||
"file": "pdfs/fips197.pdf",
|
||||
"link": true,
|
||||
|
@ -258,7 +258,7 @@ var Type2Parser = function(aFilePath) {
|
||||
var count = decoded.length;
|
||||
for (var i = 0; i < count; i++) {
|
||||
var token = decoded[i];
|
||||
if (IsNum(token)) {
|
||||
if (isNum(token)) {
|
||||
stack.push(token);
|
||||
} else {
|
||||
switch (token.operand) {
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
<div class="separator"></div>
|
||||
|
||||
<input type="text" id="pageNumber" onchange="PDFView.page = this.value;" value="1" size="4"/>
|
||||
<input type="number" id="pageNumber" onchange="PDFView.page = this.value;" value="1" size="4" min="1" />
|
||||
|
||||
<span>/</span>
|
||||
<span id="numPages">--</span>
|
||||
|
148
web/viewer.js
148
web/viewer.js
@ -9,6 +9,8 @@ var kDefaultScaleDelta = 1.1;
|
||||
var kCacheSize = 20;
|
||||
var kCssUnits = 96.0 / 72.0;
|
||||
var kScrollbarPadding = 40;
|
||||
var kMinScale = 0.25;
|
||||
var kMaxScale = 4.0;
|
||||
|
||||
|
||||
var Cache = function(size) {
|
||||
@ -21,11 +23,13 @@ var Cache = function(size) {
|
||||
};
|
||||
|
||||
var cache = new Cache(kCacheSize);
|
||||
var currentPageNumber = 1;
|
||||
|
||||
var PDFView = {
|
||||
pages: [],
|
||||
thumbnails: [],
|
||||
currentScale: kDefaultScale,
|
||||
initialBookmark: document.location.hash.substring(1),
|
||||
|
||||
setScale: function(val, resetAutoSettings) {
|
||||
var pages = this.pages;
|
||||
@ -33,11 +37,8 @@ var PDFView = {
|
||||
pages[i].update(val * kCssUnits);
|
||||
this.currentScale = val;
|
||||
|
||||
if (document.location.hash == '#' + this.page)
|
||||
this.pages[this.page - 1].draw();
|
||||
else
|
||||
// Jump the scroll position to the correct page.
|
||||
document.location.hash = this.page;
|
||||
this.pages[this.page - 1].scrollIntoView();
|
||||
this.pages[this.page - 1].draw();
|
||||
|
||||
var event = document.createEvent('UIEvents');
|
||||
event.initUIEvent('scalechange', false, false, window, 0);
|
||||
@ -72,11 +73,13 @@ var PDFView = {
|
||||
},
|
||||
|
||||
zoomIn: function() {
|
||||
this.setScale(this.currentScale * kDefaultScaleDelta, true);
|
||||
var newScale = Math.min(kMaxScale, this.currentScale * kDefaultScaleDelta);
|
||||
this.setScale(newScale, true);
|
||||
},
|
||||
|
||||
zoomOut: function() {
|
||||
this.setScale(this.currentScale / kDefaultScaleDelta, true);
|
||||
var newScale = Math.max(kMinScale, this.currentScale / kDefaultScaleDelta);
|
||||
this.setScale(newScale, true);
|
||||
},
|
||||
|
||||
set page(val) {
|
||||
@ -87,18 +90,18 @@ var PDFView = {
|
||||
return;
|
||||
}
|
||||
|
||||
document.location.hash = val;
|
||||
currentPageNumber = val;
|
||||
document.getElementById('previous').disabled = (val == 1);
|
||||
document.getElementById('next').disabled = (val == pages.length);
|
||||
if (input.value == val)
|
||||
return;
|
||||
if (input.value != val) {
|
||||
input.value = val;
|
||||
}
|
||||
|
||||
input.value = val;
|
||||
pages[val - 1].draw();
|
||||
pages[val - 1].scrollIntoView();
|
||||
},
|
||||
|
||||
get page() {
|
||||
return parseInt(document.location.hash.substring(1), 10) || 1;
|
||||
return currentPageNumber;
|
||||
},
|
||||
|
||||
open: function(url, scale) {
|
||||
@ -107,28 +110,18 @@ var PDFView = {
|
||||
|
||||
document.title = url;
|
||||
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', url);
|
||||
xhr.mozResponseType = xhr.responseType = 'arraybuffer';
|
||||
xhr.expected = (document.URL.indexOf('file:') === 0) ? 0 : 200;
|
||||
xhr.onprogress = PDFView.progressLevel;
|
||||
|
||||
xhr.onreadystatechange = function() {
|
||||
if (xhr.readyState === 4 && xhr.status === xhr.expected) {
|
||||
var data = (xhr.mozResponseArrayBuffer || xhr.mozResponse ||
|
||||
xhr.responseArrayBuffer || xhr.response);
|
||||
|
||||
document.getElementById('loading').style.display = 'none';
|
||||
getPdf(
|
||||
{
|
||||
url: url,
|
||||
progress: function getPdfProgress(evt) {
|
||||
if (evt.lengthComputable)
|
||||
PDFView.progress(evt.loaded / evt.total);
|
||||
},
|
||||
error: PDFView.error
|
||||
},
|
||||
function getPdfLoad(data) {
|
||||
PDFView.load(data, scale);
|
||||
}
|
||||
};
|
||||
|
||||
xhr.send(null);
|
||||
},
|
||||
|
||||
progressLevel: function(evt) {
|
||||
var p = Math.round((evt.loaded / evt.total) * 100);
|
||||
document.getElementById('loading').innerHTML = 'Loading... ' + p + '%';
|
||||
});
|
||||
},
|
||||
|
||||
navigateTo: function(dest) {
|
||||
@ -147,7 +140,36 @@ var PDFView = {
|
||||
}
|
||||
},
|
||||
|
||||
getDestinationHash: function(dest) {
|
||||
if (typeof dest === 'string')
|
||||
return '#' + escape(dest);
|
||||
if (dest instanceof Array) {
|
||||
var destRef = dest[0]; // see nevigateTo method for dest format
|
||||
var pageNumber = destRef instanceof Object ?
|
||||
this.pagesRefMap[destRef.num + ' ' + destRef.gen + ' R'] :
|
||||
(destRef + 1);
|
||||
if (pageNumber) {
|
||||
return '#page=' + pageNumber + '&dest=' + dest.slice(1).join(',');
|
||||
}
|
||||
}
|
||||
return '';
|
||||
},
|
||||
|
||||
error: function() {
|
||||
var loadingIndicator = document.getElementById('loading');
|
||||
loadingIndicator.innerHTML = 'Error';
|
||||
},
|
||||
|
||||
progress: function(level) {
|
||||
var percent = Math.round(level * 100);
|
||||
var loadingIndicator = document.getElementById('loading');
|
||||
loadingIndicator.innerHTML = 'Loading... ' + percent + '%';
|
||||
},
|
||||
|
||||
load: function(data, scale) {
|
||||
var loadingIndicator = document.getElementById('loading');
|
||||
loadingIndicator.style.display = 'none';
|
||||
|
||||
var sidebar = document.getElementById('sidebarView');
|
||||
sidebar.parentNode.scrollTop = 0;
|
||||
|
||||
@ -162,6 +184,7 @@ var PDFView = {
|
||||
var pdf = new PDFDoc(data);
|
||||
var pagesCount = pdf.numPages;
|
||||
document.getElementById('numPages').innerHTML = pagesCount;
|
||||
document.getElementById('pageNumber').max = pagesCount;
|
||||
|
||||
var pages = this.pages = [];
|
||||
var pagesRefMap = {};
|
||||
@ -177,7 +200,7 @@ var PDFView = {
|
||||
}
|
||||
|
||||
this.setScale(scale || kDefaultScale, true);
|
||||
this.page = parseInt(document.location.hash.substring(1), 10) || 1;
|
||||
|
||||
this.pagesRefMap = pagesRefMap;
|
||||
this.destinations = pdf.catalog.destinations;
|
||||
if (pdf.catalog.documentOutline) {
|
||||
@ -186,6 +209,28 @@ var PDFView = {
|
||||
outlineSwitchButton.removeAttribute('disabled');
|
||||
this.switchSidebarView('outline');
|
||||
}
|
||||
|
||||
if (this.initialBookmark) {
|
||||
this.setHash(this.initialBookmark);
|
||||
this.initialBookmark = null;
|
||||
}
|
||||
else
|
||||
this.page = 1;
|
||||
},
|
||||
|
||||
setHash: function(hash) {
|
||||
if (!hash)
|
||||
return;
|
||||
|
||||
if (hash.indexOf('=') >= 0) {
|
||||
// TODO more complex hashes, for now catching page=XX only
|
||||
var m = /\bpage=(\d+)/.exec(hash);
|
||||
if (m && m[1] > 0)
|
||||
this.page = m[1];
|
||||
} else if (/^\d+$/.test(hash)) // page number
|
||||
this.page = hash;
|
||||
else // named destination
|
||||
PDFView.navigateTo(unescape(hash));
|
||||
},
|
||||
|
||||
switchSidebarView: function(view) {
|
||||
@ -270,6 +315,7 @@ var PageView = function(container, content, id, pageWidth, pageHeight,
|
||||
|
||||
function setupLinks(content, scale) {
|
||||
function bindLink(link, dest) {
|
||||
link.href = PDFView.getDestinationHash(dest);
|
||||
link.onclick = function() {
|
||||
if (dest)
|
||||
PDFView.navigateTo(dest);
|
||||
@ -292,6 +338,11 @@ var PageView = function(container, content, id, pageWidth, pageHeight,
|
||||
}
|
||||
|
||||
this.scrollIntoView = function(dest) {
|
||||
if (!dest) {
|
||||
div.scrollIntoView(true);
|
||||
return;
|
||||
}
|
||||
|
||||
var x = 0, y = 0;
|
||||
var width = 0, height = 0, widthScale, heightScale;
|
||||
var scale = 0;
|
||||
@ -401,6 +452,10 @@ var PageView = function(container, content, id, pageWidth, pageHeight,
|
||||
var ThumbnailView = function(container, page, id, pageRatio) {
|
||||
var anchor = document.createElement('a');
|
||||
anchor.href = '#' + id;
|
||||
anchor.onclick = function stopNivigation() {
|
||||
PDFView.page = id;
|
||||
return false;
|
||||
};
|
||||
|
||||
var div = document.createElement('div');
|
||||
div.id = 'thumbnailContainer' + id;
|
||||
@ -448,7 +503,7 @@ var DocumentOutlineView = function(outline) {
|
||||
var outlineView = document.getElementById('outlineView');
|
||||
|
||||
function bindItemLink(domObj, item) {
|
||||
domObj.href = '';
|
||||
domObj.href = PDFView.getDestinationHash(item.dest);
|
||||
domObj.onclick = function(e) {
|
||||
PDFView.navigateTo(item.dest);
|
||||
return false;
|
||||
@ -495,10 +550,18 @@ window.addEventListener('load', function(evt) {
|
||||
document.getElementById('fileInput').value = null;
|
||||
}, true);
|
||||
|
||||
window.addEventListener('pdfloaded', function(evt) {
|
||||
window.addEventListener('pdfload', function(evt) {
|
||||
PDFView.load(evt.detail);
|
||||
}, true);
|
||||
|
||||
window.addEventListener('pdfprogress', function(evt) {
|
||||
PDFView.progress(evt.detail);
|
||||
}, true);
|
||||
|
||||
window.addEventListener('pdferror', function(evt) {
|
||||
PDFView.error();
|
||||
}, true);
|
||||
|
||||
function updateViewarea() {
|
||||
var visiblePages = PDFView.getVisiblePages();
|
||||
for (var i = 0; i < visiblePages.length; i++) {
|
||||
@ -531,7 +594,7 @@ window.addEventListener('resize', function onscroll(evt) {
|
||||
});
|
||||
|
||||
window.addEventListener('hashchange', function(evt) {
|
||||
PDFView.page = PDFView.page;
|
||||
PDFView.setHash(document.location.hash.substring(1));
|
||||
});
|
||||
|
||||
window.addEventListener('change', function(evt) {
|
||||
@ -557,7 +620,6 @@ window.addEventListener('change', function(evt) {
|
||||
fileReader.readAsBinaryString(file);
|
||||
|
||||
document.title = file.name;
|
||||
document.location.hash = 1;
|
||||
}, true);
|
||||
|
||||
window.addEventListener('transitionend', function(evt) {
|
||||
@ -609,13 +671,19 @@ window.addEventListener('scalechange', function scalechange(evt) {
|
||||
|
||||
window.addEventListener('pagechange', function pagechange(evt) {
|
||||
var page = evt.detail;
|
||||
document.location.hash = page;
|
||||
document.getElementById('pageNumber').value = page;
|
||||
document.getElementById('previous').disabled = (page == 1);
|
||||
document.getElementById('next').disabled = (page == PDFView.pages.length);
|
||||
}, true);
|
||||
|
||||
window.addEventListener('keydown', function keydown(evt) {
|
||||
var curElement = document.activeElement;
|
||||
var controlsElement = document.getElementById('controls');
|
||||
while (curElement) {
|
||||
if (curElement === controlsElement)
|
||||
return; // ignoring if the 'controls' element is focused
|
||||
curElement = curElement.parentNode;
|
||||
}
|
||||
switch (evt.keyCode) {
|
||||
case 61: // FF/Mac '='
|
||||
case 107: // FF '+' and '='
|
||||
|
Loading…
x
Reference in New Issue
Block a user