1
0
Fork 0
mirror of https://github.com/mozilla/pdf.js.git synced 2025-04-20 15:18:08 +02:00

Implement progressive loading of PDFs

This commit is contained in:
Mack Duan 2013-02-06 15:19:29 -08:00
parent added3da8f
commit ef423ef30c
25 changed files with 2110 additions and 586 deletions

View file

@ -28,7 +28,8 @@
// PDFJS.disableWorker = true;
PDFJS.enableStats = true;
var appPath, browser, canvas, dummyCanvas, currentTaskIdx, manifest, stdout;
var appPath, masterMode, browser, canvas, dummyCanvas, currentTaskIdx,
manifest, stdout;
var inFlightRequests = 0;
function queryParams() {
@ -47,6 +48,7 @@ function load() {
browser = params.browser;
var manifestFile = params.manifestFile;
appPath = params.path;
masterMode = params.masterMode === 'True';
var delay = params.delay || 0;
canvas = document.createElement('canvas');
@ -124,27 +126,28 @@ function nextTask() {
log('Loading file "' + task.file + '"\n');
var absoluteUrl = combineUrl(window.location.href, task.file);
getPdf(absoluteUrl, function nextTaskGetPdf(data) {
var failure;
function continuation() {
task.pageNum = task.firstPage || 1;
nextPage(task, failure);
}
try {
var promise = PDFJS.getDocument(data);
promise.then(function(doc) {
task.pdfDoc = doc;
continuation();
}, function(e) {
failure = 'load PDF doc : ' + e;
continuation();
});
return;
} catch (e) {
failure = 'load PDF doc : ' + exceptionToString(e);
}
continuation();
});
var failure;
function continuation() {
task.pageNum = task.firstPage || 1;
nextPage(task, failure);
}
// When generating reference images in masterMode, disable range requests
PDFJS.disableRange = !task.rangeRequest || masterMode;
try {
var promise = PDFJS.getDocument(absoluteUrl);
promise.then(function(doc) {
task.pdfDoc = doc;
continuation();
}, function(e) {
failure = 'load PDF doc : ' + e;
continuation();
});
return;
} catch (e) {
failure = 'load PDF doc : ' + exceptionToString(e);
}
continuation();
}
function getLastPageNum(task) {

View file

@ -12,6 +12,9 @@
<script type="text/javascript" src="fontutils.js"></script>
<!-- include source files here... -->
<script type="text/javascript" src="../../src/network.js"></script>
<script type="text/javascript" src="../../src/chunked_stream.js"></script>
<script type="text/javascript" src="../../src/pdf_manager.js"></script>
<script type="text/javascript" src="../../src/core.js"></script>
<script type="text/javascript" src="../../src/api.js"></script>
<script type="text/javascript" src="../../src/util.js"></script>

View file

@ -3,6 +3,7 @@
!tracemonkey.pdf
!issue2391-1.pdf
!issue2391-2.pdf
!filled-background.pdf
!ArabicCIDTrueType.pdf
!ThuluthFeatures.pdf
!arial_unicode_ab_cidfont.pdf

File diff suppressed because one or more lines are too long

View file

@ -88,6 +88,7 @@ class TestOptions(OptionParser):
return options
def prompt(question):
'''Return True iff the user answered "yes" to |question|.'''
inp = raw_input(question +' [yes/no] > ')
@ -157,12 +158,32 @@ class TestHandlerBase(BaseHTTPRequestHandler):
def sendFile(self, path, ext):
self.send_response(200)
self.send_header("Accept-Ranges", "bytes")
self.send_header("Content-Type", MIMEs[ext])
self.send_header("Content-Length", os.path.getsize(path))
self.end_headers()
with open(path, "rb") as f:
self.wfile.write(f.read())
def sendFileRange(self, path, ext, start, end):
file_len = os.path.getsize(path)
if (end is None) or (file_len < end):
end = file_len
if (file_len < start) or (end <= start):
self.send_error(416)
return
chunk_len = end - start
self.send_response(206)
self.send_header("Accept-Ranges", "bytes")
self.send_header("Content-Type", MIMEs[ext])
self.send_header("Content-Length", chunk_len)
self.send_header("Content-Range", 'bytes ' + str(start) + '-' + str(end - 1) + '/' + str(file_len))
self.end_headers()
time.sleep(chunk_len / 500000.0)
with open(path, "rb") as f:
f.seek(start)
self.wfile.write(f.read(chunk_len))
def do_GET(self):
url = urlparse(self.path)
@ -188,8 +209,18 @@ class TestHandlerBase(BaseHTTPRequestHandler):
return
if 'Range' in self.headers:
# TODO for fetch-as-you-go
self.send_error(501)
range_re = re.compile(r"^bytes=(\d+)\-(\d+)?")
parsed_range = range_re.search(self.headers.getheader("Range"))
if parsed_range is None:
self.send_error(501)
return
print 'Range requested ' + parsed_range.group(1) + '-' + parsed_range.group(2)
start = int(parsed_range.group(1))
if parsed_range.group(2) is None:
self.sendFileRange(path, ext, start, None)
else:
end = int(parsed_range.group(2)) + 1
self.sendFileRange(path, ext, start, end)
return
self.sendFile(path, ext)
@ -606,6 +637,7 @@ def startBrowsers(browsers, options, path):
qs = '?browser='+ urllib.quote(b.name) +'&manifestFile='+ urllib.quote(options.manifestFile)
qs += '&path=' + b.path
qs += '&delay=' + str(options.statsDelay)
qs += '&masterMode=' + str(options.masterMode)
b.start(host + path + qs)
def teardownBrowsers(browsers):

View file

@ -1,4 +1,11 @@
[
{ "id": "filled-background-range",
"file": "pdfs/filled-background.pdf",
"md5": "2e3120255d9c3e79b96d2543b12d2589",
"rounds": 1,
"rangeRequest": true,
"type": "eq"
},
{ "id": "tracemonkey-eq",
"file": "pdfs/tracemonkey.pdf",
"md5": "9a192d8b1a7dc652a19835f6f08098bd",

View file

@ -19,6 +19,9 @@ limitations under the License.
<head>
<title>pdf.js test slave</title>
<style type="text/css"></style>
<script type="text/javascript" src="/src/network.js"></script>
<script type="text/javascript" src="/src/chunked_stream.js"></script>
<script type="text/javascript" src="/src/pdf_manager.js"></script>
<script type="text/javascript" src="/src/core.js"></script>
<script type="text/javascript" src="/src/util.js"></script>
<script type="text/javascript" src="/src/api.js"></script>

View file

@ -11,6 +11,9 @@
<script type="text/javascript" src="testreporter.js"></script>
<!-- include source files here... -->
<script type="text/javascript" src="../../src/network.js"></script>
<script type="text/javascript" src="../../src/chunked_stream.js"></script>
<script type="text/javascript" src="../../src/pdf_manager.js"></script>
<script type="text/javascript" src="../../src/core.js"></script>
<script type="text/javascript" src="../../src/api.js"></script>
<script type="text/javascript" src="../../src/util.js"></script>