Merge branch 'refs/heads/master' into issue-1049
Conflicts: src/canvas.js
This commit is contained in:
commit
7873ec966b
6
Makefile
6
Makefile
@ -3,6 +3,7 @@ BUILD_DIR := build
|
||||
BUILD_TARGET := $(BUILD_DIR)/pdf.js
|
||||
DEFAULT_BROWSERS := resources/browser_manifests/browser_manifest.json
|
||||
DEFAULT_TESTS := test_manifest.json
|
||||
DEFAULT_PYTHON := python2.7
|
||||
|
||||
EXTENSION_SRC := ./extensions/
|
||||
EXTENSION_BASE_VERSION := 4bb289ec499013de66eb421737a4dbb4a9273eda
|
||||
@ -36,6 +37,7 @@ PDF_JS_FILES = \
|
||||
stream.js \
|
||||
worker.js \
|
||||
../external/jpgjs/jpg.js \
|
||||
jpx.js \
|
||||
$(NULL)
|
||||
|
||||
# make server
|
||||
@ -43,7 +45,7 @@ PDF_JS_FILES = \
|
||||
# This target starts a local web server at localhost:8888. This can be
|
||||
# used for testing all browsers.
|
||||
server:
|
||||
@cd test; python test.py --port=8888;
|
||||
@cd test; $(DEFAULT_PYTHON) test.py --port=8888;
|
||||
|
||||
# make test
|
||||
#
|
||||
@ -106,7 +108,7 @@ browser-test:
|
||||
fi;
|
||||
|
||||
cd test; \
|
||||
python test.py --reftest \
|
||||
$(DEFAULT_PYTHON) test.py --reftest \
|
||||
--browserManifestFile=$(PDF_BROWSERS) \
|
||||
--manifestFile=$(PDF_TESTS)
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
<script type="text/javascript" src="../../src/stream.js"></script>
|
||||
<script type="text/javascript" src="../../src/worker.js"></script>
|
||||
<script type="text/javascript" src="../../external/jpgjs/jpg.js"></script>
|
||||
<script type="text/javascript" src="../../src/jpx.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
// Specify the main script used to create a new PDF.JS web worker.
|
||||
|
@ -23,6 +23,7 @@
|
||||
<script type="text/javascript" src="../../src/stream.js"></script>
|
||||
<script type="text/javascript" src="../../src/worker.js"></script>
|
||||
<script type="text/javascript" src="../../external/jpgjs/jpg.js"></script>
|
||||
<script type="text/javascript" src="../../src/jpx.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
// Specify the main script used to create a new PDF.JS web worker.
|
||||
|
@ -550,7 +550,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
var current = this.current;
|
||||
|
||||
if (!fontObj)
|
||||
throw 'Can\'t find font for ' + fontRefName;
|
||||
error('Can\'t find font for ' + fontRefName);
|
||||
|
||||
// Slice-clone matrix so we can manipulate it without affecting original
|
||||
if (fontObj.fontMatrix)
|
||||
@ -889,7 +889,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
} else if (IR[0] == 'RadialAxial' || IR[0] == 'Dummy') {
|
||||
var pattern = Pattern.shadingFromIR(this.ctx, IR);
|
||||
} else {
|
||||
throw 'Unkown IR type';
|
||||
error('Unkown IR type ' + IR[0]);
|
||||
}
|
||||
return pattern;
|
||||
},
|
||||
|
@ -369,55 +369,16 @@ var DeviceCmykCS = (function DeviceCmykCSClosure() {
|
||||
DeviceCmykCS.prototype = {
|
||||
getRgb: function cmykcs_getRgb(color) {
|
||||
var c = color[0], m = color[1], y = color[2], k = color[3];
|
||||
var c1 = 1 - c, m1 = 1 - m, y1 = 1 - y, k1 = 1 - k;
|
||||
|
||||
var x, r, g, b;
|
||||
// this is a matrix multiplication, unrolled for performance
|
||||
// code is taken from the poppler implementation
|
||||
x = c1 * m1 * y1 * k1; // 0 0 0 0
|
||||
r = g = b = x;
|
||||
x = c1 * m1 * y1 * k; // 0 0 0 1
|
||||
r += 0.1373 * x;
|
||||
g += 0.1216 * x;
|
||||
b += 0.1255 * x;
|
||||
x = c1 * m1 * y * k1; // 0 0 1 0
|
||||
r += x;
|
||||
g += 0.9490 * x;
|
||||
x = c1 * m1 * y * k; // 0 0 1 1
|
||||
r += 0.1098 * x;
|
||||
g += 0.1020 * x;
|
||||
x = c1 * m * y1 * k1; // 0 1 0 0
|
||||
r += 0.9255 * x;
|
||||
b += 0.5490 * x;
|
||||
x = c1 * m * y1 * k; // 0 1 0 1
|
||||
r += 0.1412 * x;
|
||||
x = c1 * m * y * k1; // 0 1 1 0
|
||||
r += 0.9294 * x;
|
||||
g += 0.1098 * x;
|
||||
b += 0.1412 * x;
|
||||
x = c1 * m * y * k; // 0 1 1 1
|
||||
r += 0.1333 * x;
|
||||
x = c * m1 * y1 * k1; // 1 0 0 0
|
||||
g += 0.6784 * x;
|
||||
b += 0.9373 * x;
|
||||
x = c * m1 * y1 * k; // 1 0 0 1
|
||||
g += 0.0588 * x;
|
||||
b += 0.1412 * x;
|
||||
x = c * m1 * y * k1; // 1 0 1 0
|
||||
g += 0.6510 * x;
|
||||
b += 0.3137 * x;
|
||||
x = c * m1 * y * k; // 1 0 1 1
|
||||
g += 0.0745 * x;
|
||||
x = c * m * y1 * k1; // 1 1 0 0
|
||||
r += 0.1804 * x;
|
||||
g += 0.1922 * x;
|
||||
b += 0.5725 * x;
|
||||
x = c * m * y1 * k; // 1 1 0 1
|
||||
b += 0.0078 * x;
|
||||
x = c * m * y * k1; // 1 1 1 0
|
||||
r += 0.2118 * x;
|
||||
g += 0.2119 * x;
|
||||
b += 0.2235 * x;
|
||||
// CMYK -> CMY: http://www.easyrgb.com/index.php?X=MATH&H=14#text14
|
||||
c = (c * (1 - k) + k);
|
||||
m = (m * (1 - k) + k);
|
||||
y = (y * (1 - k) + k);
|
||||
|
||||
// CMY -> RGB: http://www.easyrgb.com/index.php?X=MATH&H=12#text12
|
||||
var r = (1 - c);
|
||||
var g = (1 - m);
|
||||
var b = (1 - y);
|
||||
|
||||
return [r, g, b];
|
||||
},
|
||||
|
10
src/core.js
10
src/core.js
@ -410,14 +410,14 @@ var Page = (function PageClosure() {
|
||||
if (callback)
|
||||
callback(e);
|
||||
else
|
||||
throw e;
|
||||
error(e);
|
||||
}
|
||||
}.bind(this),
|
||||
function pageDisplayReadPromiseError(reason) {
|
||||
if (callback)
|
||||
callback(reason);
|
||||
else
|
||||
throw reason;
|
||||
error(reason);
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -620,7 +620,7 @@ var PDFDoc = (function PDFDocClosure() {
|
||||
if (!globalScope.PDFJS.disableWorker && typeof Worker !== 'undefined') {
|
||||
var workerSrc = PDFJS.workerSrc;
|
||||
if (typeof workerSrc === 'undefined') {
|
||||
throw 'No PDFJS.workerSrc specified';
|
||||
error('No PDFJS.workerSrc specified');
|
||||
}
|
||||
|
||||
try {
|
||||
@ -716,7 +716,7 @@ var PDFDoc = (function PDFDocClosure() {
|
||||
});
|
||||
break;
|
||||
default:
|
||||
throw 'Got unkown object type ' + type;
|
||||
error('Got unkown object type ' + type);
|
||||
}
|
||||
}, this);
|
||||
|
||||
@ -737,7 +737,7 @@ var PDFDoc = (function PDFDocClosure() {
|
||||
if (page.displayReadyPromise)
|
||||
page.displayReadyPromise.reject(data.error);
|
||||
else
|
||||
throw data.error;
|
||||
error(data.error);
|
||||
}, this);
|
||||
|
||||
messageHandler.on('jpeg_decode', function(data, promise) {
|
||||
|
@ -2235,9 +2235,8 @@ var Font = (function FontClosure() {
|
||||
}
|
||||
|
||||
// MacRoman encoding address by re-encoding the cmap table
|
||||
unicode = glyphName in GlyphsUnicode ?
|
||||
GlyphsUnicode[glyphName] :
|
||||
this.glyphNameMap[glyphName];
|
||||
unicode = glyphName in this.glyphNameMap ?
|
||||
this.glyphNameMap[glyphName] : GlyphsUnicode[glyphName];
|
||||
break;
|
||||
default:
|
||||
warn('Unsupported font type: ' + this.type);
|
||||
|
1854
src/jpx.js
Normal file
1854
src/jpx.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -574,7 +574,7 @@ var XRef = (function XRefClosure() {
|
||||
var stream, parser;
|
||||
if (e.uncompressed) {
|
||||
if (e.gen != gen)
|
||||
throw ('inconsistent generation in XRef');
|
||||
error('inconsistent generation in XRef');
|
||||
stream = this.stream.makeSubStream(e.offset);
|
||||
parser = new Parser(new Lexer(stream), true, this);
|
||||
var obj1 = parser.getObj();
|
||||
@ -703,7 +703,7 @@ var PDFObjects = (function PDFObjectsClosure() {
|
||||
// If there isn't an object yet or the object isn't resolved, then the
|
||||
// data isn't ready yet!
|
||||
if (!obj || !obj.isResolved) {
|
||||
throw 'Requesting object that isn\'t resolved yet ' + objId;
|
||||
error('Requesting object that isn\'t resolved yet ' + objId);
|
||||
return null;
|
||||
} else {
|
||||
return obj.data;
|
||||
|
@ -240,6 +240,10 @@ var Parser = (function ParserClosure() {
|
||||
var bytes = stream.getBytes(length);
|
||||
return new JpegStream(bytes, stream.dict, this.xref);
|
||||
}
|
||||
if (name == 'JPXDecode' || name == 'JPX') {
|
||||
var bytes = stream.getBytes(length);
|
||||
return new JpxStream(bytes, stream.dict);
|
||||
}
|
||||
if (name == 'ASCII85Decode' || name == 'A85') {
|
||||
return new Ascii85Stream(stream);
|
||||
}
|
||||
|
125
src/stream.js
125
src/stream.js
@ -821,21 +821,25 @@ var JpegStream = (function JpegStreamClosure() {
|
||||
JpegStream.prototype.ensureBuffer = function jpegStreamEnsureBuffer(req) {
|
||||
if (this.bufferLength)
|
||||
return;
|
||||
var jpegImage = new JpegImage();
|
||||
if (this.colorTransform != -1)
|
||||
jpegImage.colorTransform = this.colorTransform;
|
||||
jpegImage.parse(this.bytes);
|
||||
var width = jpegImage.width;
|
||||
var height = jpegImage.height;
|
||||
var data = jpegImage.getData(width, height);
|
||||
this.buffer = data;
|
||||
this.bufferLength = data.length;
|
||||
try {
|
||||
var jpegImage = new JpegImage();
|
||||
if (this.colorTransform != -1)
|
||||
jpegImage.colorTransform = this.colorTransform;
|
||||
jpegImage.parse(this.bytes);
|
||||
var width = jpegImage.width;
|
||||
var height = jpegImage.height;
|
||||
var data = jpegImage.getData(width, height);
|
||||
this.buffer = data;
|
||||
this.bufferLength = data.length;
|
||||
} catch (e) {
|
||||
error('JPEG error: ' + e);
|
||||
}
|
||||
};
|
||||
JpegStream.prototype.getIR = function jpegStreamGetIR() {
|
||||
return bytesToString(this.bytes);
|
||||
};
|
||||
JpegStream.prototype.getChar = function jpegStreamGetChar() {
|
||||
error('internal error: getChar is not valid on JpegStream');
|
||||
error('internal error: getChar is not valid on JpegStream');
|
||||
};
|
||||
/**
|
||||
* Checks if the image can be decoded and displayed by the browser without any
|
||||
@ -869,6 +873,107 @@ var JpegStream = (function JpegStreamClosure() {
|
||||
return JpegStream;
|
||||
})();
|
||||
|
||||
/**
|
||||
* For JPEG 2000's we use a library to decode these images and
|
||||
* the stream behaves like all the other DecodeStreams.
|
||||
*/
|
||||
var JpxStream = (function JpxStreamClosure() {
|
||||
function JpxStream(bytes, dict) {
|
||||
this.dict = dict;
|
||||
this.bytes = bytes;
|
||||
|
||||
DecodeStream.call(this);
|
||||
}
|
||||
|
||||
JpxStream.prototype = Object.create(DecodeStream.prototype);
|
||||
|
||||
JpxStream.prototype.ensureBuffer = function jpxStreamEnsureBuffer(req) {
|
||||
if (this.bufferLength)
|
||||
return;
|
||||
|
||||
var jpxImage = new JpxImage();
|
||||
jpxImage.parse(this.bytes);
|
||||
|
||||
var width = jpxImage.width;
|
||||
var height = jpxImage.height;
|
||||
var componentsCount = jpxImage.componentsCount;
|
||||
if (componentsCount != 1 && componentsCount != 3 && componentsCount != 4)
|
||||
error('JPX with ' + componentsCount + ' components is not supported');
|
||||
|
||||
var data = new Uint8Array(width * height * componentsCount);
|
||||
|
||||
for (var k = 0, kk = jpxImage.tiles.length; k < kk; k++) {
|
||||
var tileCompoments = jpxImage.tiles[k];
|
||||
var tileWidth = tileCompoments[0].width;
|
||||
var tileHeight = tileCompoments[0].height;
|
||||
var tileLeft = tileCompoments[0].left;
|
||||
var tileTop = tileCompoments[0].top;
|
||||
|
||||
var dataPosition, sourcePosition, data0, data1, data2, data3, rowFeed;
|
||||
switch (componentsCount) {
|
||||
case 1:
|
||||
data0 = tileCompoments[0].items;
|
||||
|
||||
dataPosition = width * tileTop + tileLeft;
|
||||
rowFeed = width - tileWidth;
|
||||
sourcePosition = 0;
|
||||
for (var j = 0; j < tileHeight; j++) {
|
||||
for (var i = 0; i < tileWidth; i++)
|
||||
data[dataPosition++] = data0[sourcePosition++];
|
||||
dataPosition += rowFeed;
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
data0 = tileCompoments[0].items;
|
||||
data1 = tileCompoments[1].items;
|
||||
data2 = tileCompoments[2].items;
|
||||
|
||||
dataPosition = (width * tileTop + tileLeft) * 3;
|
||||
rowFeed = (width - tileWidth) * 3;
|
||||
sourcePosition = 0;
|
||||
for (var j = 0; j < tileHeight; j++) {
|
||||
for (var i = 0; i < tileWidth; i++) {
|
||||
data[dataPosition++] = data0[sourcePosition];
|
||||
data[dataPosition++] = data1[sourcePosition];
|
||||
data[dataPosition++] = data2[sourcePosition];
|
||||
sourcePosition++;
|
||||
}
|
||||
dataPosition += rowFeed;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
data0 = tileCompoments[0].items;
|
||||
data1 = tileCompoments[1].items;
|
||||
data2 = tileCompoments[2].items;
|
||||
data3 = tileCompoments[3].items;
|
||||
|
||||
dataPosition = (width * tileTop + tileLeft) * 4;
|
||||
rowFeed = (width - tileWidth) * 4;
|
||||
sourcePosition = 0;
|
||||
for (var j = 0; j < tileHeight; j++) {
|
||||
for (var i = 0; i < tileWidth; i++) {
|
||||
data[dataPosition++] = data0[sourcePosition];
|
||||
data[dataPosition++] = data1[sourcePosition];
|
||||
data[dataPosition++] = data2[sourcePosition];
|
||||
data[dataPosition++] = data3[sourcePosition];
|
||||
sourcePosition++;
|
||||
}
|
||||
dataPosition += rowFeed;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
this.buffer = data;
|
||||
this.bufferLength = data.length;
|
||||
};
|
||||
JpxStream.prototype.getChar = function jpxStreamGetChar() {
|
||||
error('internal error: getChar is not valid on JpxStream');
|
||||
};
|
||||
|
||||
return JpxStream;
|
||||
})();
|
||||
|
||||
var DecryptStream = (function DecryptStreamClosure() {
|
||||
function DecryptStream(str, decrypt) {
|
||||
this.str = str;
|
||||
|
16
src/util.js
16
src/util.js
@ -259,8 +259,8 @@ var Promise = (function PromiseClosure() {
|
||||
return;
|
||||
}
|
||||
if (this._data !== EMPTY_PROMISE) {
|
||||
throw 'Promise ' + this.name +
|
||||
': Cannot set the data of a promise twice';
|
||||
error('Promise ' + this.name +
|
||||
': Cannot set the data of a promise twice');
|
||||
}
|
||||
this._data = value;
|
||||
this.hasData = true;
|
||||
@ -272,7 +272,7 @@ var Promise = (function PromiseClosure() {
|
||||
|
||||
get data() {
|
||||
if (this._data === EMPTY_PROMISE) {
|
||||
throw 'Promise ' + this.name + ': Cannot get data that isn\'t set';
|
||||
error('Promise ' + this.name + ': Cannot get data that isn\'t set');
|
||||
}
|
||||
return this._data;
|
||||
},
|
||||
@ -287,10 +287,10 @@ var Promise = (function PromiseClosure() {
|
||||
|
||||
resolve: function promiseResolve(data) {
|
||||
if (this.isResolved) {
|
||||
throw 'A Promise can be resolved only once ' + this.name;
|
||||
error('A Promise can be resolved only once ' + this.name);
|
||||
}
|
||||
if (this.isRejected) {
|
||||
throw 'The Promise was already rejected ' + this.name;
|
||||
error('The Promise was already rejected ' + this.name);
|
||||
}
|
||||
|
||||
this.isResolved = true;
|
||||
@ -304,10 +304,10 @@ var Promise = (function PromiseClosure() {
|
||||
|
||||
reject: function proimseReject(reason) {
|
||||
if (this.isRejected) {
|
||||
throw 'A Promise can be rejected only once ' + this.name;
|
||||
error('A Promise can be rejected only once ' + this.name);
|
||||
}
|
||||
if (this.isResolved) {
|
||||
throw 'The Promise was already resolved ' + this.name;
|
||||
error('The Promise was already resolved ' + this.name);
|
||||
}
|
||||
|
||||
this.isRejected = true;
|
||||
@ -321,7 +321,7 @@ var Promise = (function PromiseClosure() {
|
||||
|
||||
then: function promiseThen(callback, errback) {
|
||||
if (!callback) {
|
||||
throw 'Requiring callback' + this.name;
|
||||
error('Requiring callback' + this.name);
|
||||
}
|
||||
|
||||
// If the promise is already resolved, call the callback directly.
|
||||
|
@ -26,7 +26,7 @@ function MessageHandler(name, comObj) {
|
||||
delete callbacks[callbackId];
|
||||
callback(data.data);
|
||||
} else {
|
||||
throw 'Cannot resolve callback ' + callbackId;
|
||||
error('Cannot resolve callback ' + callbackId);
|
||||
}
|
||||
} else if (data.action in ah) {
|
||||
var action = ah[data.action];
|
||||
@ -44,7 +44,7 @@ function MessageHandler(name, comObj) {
|
||||
action[0].call(action[1], data.data);
|
||||
}
|
||||
} else {
|
||||
throw 'Unkown action from worker: ' + data.action;
|
||||
error('Unkown action from worker: ' + data.action);
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -53,7 +53,7 @@ MessageHandler.prototype = {
|
||||
on: function messageHandlerOn(actionName, handler, scope) {
|
||||
var ah = this.actionHandler;
|
||||
if (ah[actionName]) {
|
||||
throw 'There is already an actionName called "' + actionName + '"';
|
||||
error('There is already an actionName called "' + actionName + '"');
|
||||
}
|
||||
ah[actionName] = [handler, scope];
|
||||
},
|
||||
@ -224,6 +224,7 @@ var workerConsole = {
|
||||
action: 'console_error',
|
||||
data: args
|
||||
});
|
||||
throw 'pdf.js execution error';
|
||||
},
|
||||
|
||||
time: function time(name) {
|
||||
@ -233,7 +234,7 @@ var workerConsole = {
|
||||
timeEnd: function timeEnd(name) {
|
||||
var time = consoleTimer[name];
|
||||
if (time == null) {
|
||||
throw 'Unkown timer name ' + name;
|
||||
error('Unkown timer name ' + name);
|
||||
}
|
||||
this.log('Timer:', name, Date.now() - time);
|
||||
}
|
||||
|
@ -23,7 +23,8 @@ var files = [
|
||||
'pattern.js',
|
||||
'stream.js',
|
||||
'worker.js',
|
||||
'../external/jpgjs/jpg.js'
|
||||
'../external/jpgjs/jpg.js',
|
||||
'jpx.js'
|
||||
];
|
||||
|
||||
// Load all the files.
|
||||
|
1
test/pdfs/.gitignore
vendored
1
test/pdfs/.gitignore
vendored
@ -22,4 +22,5 @@
|
||||
!issue918.pdf
|
||||
!smaskdim.pdf
|
||||
!type4psfunc.pdf
|
||||
!S2.pdf
|
||||
!zerowidthline.pdf
|
||||
|
2549
test/pdfs/S2.pdf
Normal file
2549
test/pdfs/S2.pdf
Normal file
File diff suppressed because one or more lines are too long
1
test/pdfs/issue1096.pdf.link
Normal file
1
test/pdfs/issue1096.pdf.link
Normal file
@ -0,0 +1 @@
|
||||
http://www.faithaliveresources.org/Content/Site135/FilesSamples/105315400440pdf_00000009843.pdf
|
@ -402,6 +402,14 @@
|
||||
"link": true,
|
||||
"type": "eq"
|
||||
},
|
||||
{ "id": "issue1096",
|
||||
"file": "pdfs/issue1096.pdf",
|
||||
"md5": "7f75d2b4b93c78d401ff39e8c1b00612",
|
||||
"rounds": 1,
|
||||
"pageLimit": 10,
|
||||
"link": true,
|
||||
"type": "eq"
|
||||
},
|
||||
{ "id": "liveprogramming",
|
||||
"file": "pdfs/liveprogramming.pdf",
|
||||
"md5": "7bd4dad1188232ef597d36fd72c33e52",
|
||||
@ -410,6 +418,12 @@
|
||||
"link": true,
|
||||
"type": "load"
|
||||
},
|
||||
{ "id": "S2-eq",
|
||||
"file": "pdfs/S2.pdf",
|
||||
"md5": "d0b6137846df6e0fe058f234a87fb588",
|
||||
"rounds": 1,
|
||||
"type": "eq"
|
||||
},
|
||||
{ "id": "issue1055",
|
||||
"file": "pdfs/issue1055.pdf",
|
||||
"md5": "3ba56c2e48dce81da8669b1b9cf98ff0",
|
||||
|
@ -22,6 +22,7 @@
|
||||
<script type="text/javascript" src="/src/stream.js"></script>
|
||||
<script type="text/javascript" src="/src/worker.js"></script>
|
||||
<script type="text/javascript" src="/external/jpgjs/jpg.js"></script>
|
||||
<script type="text/javascript" src="/src/jpx.js"></script>
|
||||
<script type="text/javascript" src="driver.js"></script>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
@ -224,3 +224,10 @@
|
||||
}
|
||||
});
|
||||
})();
|
||||
|
||||
// Check console compatability
|
||||
(function checkConsoleCompatibility() {
|
||||
if (typeof console == 'undefined') {
|
||||
console = {log: function() {}};
|
||||
}
|
||||
})();
|
||||
|
@ -26,6 +26,7 @@
|
||||
<script type="text/javascript" src="../src/stream.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
||||
<script type="text/javascript" src="../src/worker.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
||||
<script type="text/javascript" src="../external/jpgjs/jpg.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
||||
<script type="text/javascript" src="../src/jpx.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
||||
<script type="text/javascript">PDFJS.workerSrc = '../src/worker_loader.js';</script> <!-- PDFJSSCRIPT_REMOVE -->
|
||||
<script type="text/javascript" src="viewer.js"></script>
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
var kDefaultURL = 'compressed.tracemonkey-pldi-09.pdf';
|
||||
var kDefaultScale = 'auto';
|
||||
var kDefaultScaleDelta = 1.1;
|
||||
var kUnknownScale = 0;
|
||||
var kCacheSize = 20;
|
||||
var kCssUnits = 96.0 / 72.0;
|
||||
var kScrollbarPadding = 40;
|
||||
@ -148,7 +149,7 @@ var currentPageNumber = 1;
|
||||
var PDFView = {
|
||||
pages: [],
|
||||
thumbnails: [],
|
||||
currentScale: 0,
|
||||
currentScale: kUnknownScale,
|
||||
currentScaleValue: null,
|
||||
initialBookmark: document.location.hash.substring(1),
|
||||
|
||||
@ -203,12 +204,12 @@ var PDFView = {
|
||||
|
||||
zoomIn: function pdfViewZoomIn() {
|
||||
var newScale = Math.min(kMaxScale, this.currentScale * kDefaultScaleDelta);
|
||||
this.setScale(newScale, true);
|
||||
this.parseScale(newScale, true);
|
||||
},
|
||||
|
||||
zoomOut: function pdfViewZoomOut() {
|
||||
var newScale = Math.max(kMinScale, this.currentScale / kDefaultScaleDelta);
|
||||
this.setScale(newScale, true);
|
||||
this.parseScale(newScale, true);
|
||||
},
|
||||
|
||||
set page(val) {
|
||||
@ -458,10 +459,16 @@ var PDFView = {
|
||||
}
|
||||
else if (storedHash)
|
||||
this.setHash(storedHash);
|
||||
else {
|
||||
this.parseScale(scale || kDefaultScale, true);
|
||||
else if (scale) {
|
||||
this.parseScale(scale, true);
|
||||
this.page = 1;
|
||||
}
|
||||
|
||||
if (PDFView.currentScale === kUnknownScale) {
|
||||
// Scale was not initialized: invalid bookmark or scale was not specified.
|
||||
// Setting the default one.
|
||||
this.parseScale(kDefaultScale, true);
|
||||
}
|
||||
},
|
||||
|
||||
setHash: function pdfViewSetHash(hash) {
|
||||
@ -748,6 +755,8 @@ var PageView = function pageView(container, content, id, pageWidth, pageHeight,
|
||||
|
||||
if (scale && scale !== PDFView.currentScale)
|
||||
PDFView.parseScale(scale, true);
|
||||
else if (PDFView.currentScale === kUnknownScale)
|
||||
PDFView.parseScale(kDefaultScale, true);
|
||||
|
||||
setTimeout(function pageViewScrollIntoViewRelayout() {
|
||||
// letting page to re-layout before scrolling
|
||||
@ -966,22 +975,55 @@ var TextLayerBuilder = function textLayerBuilder(textLayerDiv) {
|
||||
var self = this;
|
||||
var textDivs = this.textDivs;
|
||||
var textLayerDiv = this.textLayerDiv;
|
||||
this.textLayerTimer = setInterval(function renderTextLayer() {
|
||||
var renderTimer = null;
|
||||
var renderingDone = false;
|
||||
var renderInterval = 0;
|
||||
var resumeInterval = 500; // in ms
|
||||
|
||||
// Render the text layer, one div at a time
|
||||
function renderTextLayer() {
|
||||
if (textDivs.length === 0) {
|
||||
clearInterval(self.textLayerTimer);
|
||||
clearInterval(renderTimer);
|
||||
renderingDone = true;
|
||||
return;
|
||||
}
|
||||
var textDiv = textDivs.shift();
|
||||
if (textDiv.dataset.textLength >= 1) { // avoid div by zero
|
||||
if (textDiv.dataset.textLength > 0) {
|
||||
textLayerDiv.appendChild(textDiv);
|
||||
// Adjust div width (via letterSpacing) to match canvas text
|
||||
// Due to the .offsetWidth calls, this is slow
|
||||
textDiv.style.letterSpacing =
|
||||
((textDiv.dataset.canvasWidth - textDiv.offsetWidth) /
|
||||
(textDiv.dataset.textLength - 1)) + 'px';
|
||||
|
||||
if (textDiv.dataset.textLength > 1) { // avoid div by zero
|
||||
// Adjust div width (via letterSpacing) to match canvas text
|
||||
// Due to the .offsetWidth calls, this is slow
|
||||
// This needs to come after appending to the DOM
|
||||
textDiv.style.letterSpacing =
|
||||
((textDiv.dataset.canvasWidth - textDiv.offsetWidth) /
|
||||
(textDiv.dataset.textLength - 1)) + 'px';
|
||||
}
|
||||
} // textLength > 0
|
||||
}
|
||||
renderTimer = setInterval(renderTextLayer, renderInterval);
|
||||
|
||||
// Stop rendering when user scrolls. Resume after XXX milliseconds
|
||||
// of no scroll events
|
||||
var scrollTimer = null;
|
||||
function textLayerOnScroll() {
|
||||
if (renderingDone) {
|
||||
window.removeEventListener('scroll', textLayerOnScroll, false);
|
||||
return;
|
||||
}
|
||||
}, 0);
|
||||
};
|
||||
|
||||
// Immediately pause rendering
|
||||
clearInterval(renderTimer);
|
||||
|
||||
clearTimeout(scrollTimer);
|
||||
scrollTimer = setTimeout(function textLayerScrollTimer() {
|
||||
// Resume rendering
|
||||
renderTimer = setInterval(renderTextLayer, renderInterval);
|
||||
}, resumeInterval);
|
||||
}; // textLayerOnScroll
|
||||
|
||||
window.addEventListener('scroll', textLayerOnScroll, false);
|
||||
}; // endLayout
|
||||
|
||||
this.appendText = function textLayerBuilderAppendText(text,
|
||||
fontName, fontSize) {
|
||||
@ -1240,7 +1282,7 @@ window.addEventListener('keydown', function keydown(evt) {
|
||||
handled = true;
|
||||
break;
|
||||
case 48: // '0'
|
||||
PDFView.setScale(kDefaultScale, true);
|
||||
PDFView.parseScale(kDefaultScale, true);
|
||||
handled = true;
|
||||
break;
|
||||
case 37: // left arrow
|
||||
|
Loading…
Reference in New Issue
Block a user