From eb17d81316e8ba01a9d27d7263769995f13b93b5 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Mon, 4 Jul 2011 16:14:04 -0400 Subject: [PATCH 01/15] fix test.py bug on windows and stomped failure messages --- test/test.py | 2 +- test/test_slave.html | 51 ++++++++++++++++++++++++-------------------- 2 files changed, 29 insertions(+), 24 deletions(-) diff --git a/test/test.py b/test/test.py index 52e91476a..367347e88 100644 --- a/test/test.py +++ b/test/test.py @@ -99,7 +99,7 @@ class PDFTestHandler(BaseHTTPRequestHandler): self.send_header("Content-Type", MIMEs[ext]) self.send_header("Content-Length", os.path.getsize(path)) self.end_headers() - with open(path) as f: + with open(path, "rb") as f: self.wfile.write(f.read()) def do_GET(self): diff --git a/test/test_slave.html b/test/test_slave.html index 3180418fa..0bf254ad5 100644 --- a/test/test_slave.html +++ b/test/test_slave.html @@ -88,31 +88,35 @@ function nextPage() { } } - failure = ''; - log(" loading page "+ currentTask.pageNum +"... "); - - var ctx = canvas.getContext("2d"); - - var fonts = []; - var gfx = null; - try { - gfx = new CanvasGraphics(ctx); - currentPage = pdfDoc.getPage(currentTask.pageNum); - currentPage.compile(gfx, fonts); - } catch(e) { - failure = 'compile: '+ e.toString(); + var ctx, fonts, gfx; + if (!failure) { + log(" loading page "+ currentTask.pageNum +"... "); + + ctx = canvas.getContext("2d"); + + fonts = []; + gfx = null; + try { + gfx = new CanvasGraphics(ctx); + currentPage = pdfDoc.getPage(currentTask.pageNum); + currentPage.compile(gfx, fonts); + } catch(e) { + failure = 'compile: '+ e.toString(); + } } - try { - var pdfToCssUnitsCoef = 96.0 / 72.0; - // using mediaBox for the canvas size - var pageWidth = (currentPage.mediaBox[2] - currentPage.mediaBox[0]); - var pageHeight = (currentPage.mediaBox[3] - currentPage.mediaBox[1]); - canvas.width = pageWidth * pdfToCssUnitsCoef; - canvas.height = pageHeight * pdfToCssUnitsCoef; - clear(ctx); - } catch(e) { - failure = 'page setup: '+ e.toString(); + if (!failure) { + try { + var pdfToCssUnitsCoef = 96.0 / 72.0; + // using mediaBox for the canvas size + var pageWidth = (currentPage.mediaBox[2] - currentPage.mediaBox[0]); + var pageHeight = (currentPage.mediaBox[3] - currentPage.mediaBox[1]); + canvas.width = pageWidth * pdfToCssUnitsCoef; + canvas.height = pageHeight * pdfToCssUnitsCoef; + clear(ctx); + } catch(e) { + failure = 'page setup: '+ e.toString(); + } } if (!failure) { @@ -145,6 +149,7 @@ function snapshotCurrentPage(gfx) { log("done"+ (failure ? " (failed!)" : "") +"\n"); // Set up the next request + failure = ''; backoff = (inFlightRequests > 0) ? inFlightRequests * 10 : 0; setTimeout(function() { ++currentTask.pageNum, nextPage(); From a4f8251d108908f8fe9c3ac2b62ba97a15aa6c85 Mon Sep 17 00:00:00 2001 From: Rob Sayre Date: Mon, 4 Jul 2011 14:17:23 -0700 Subject: [PATCH 02/15] Make test driver a separate js file, eradicate some global variables. --- test/driver.js | 228 +++++++++++++++++++++++++++++++++++++++++++ test/test_slave.html | 217 +--------------------------------------- 2 files changed, 229 insertions(+), 216 deletions(-) create mode 100644 test/driver.js diff --git a/test/driver.js b/test/driver.js new file mode 100644 index 000000000..e7fb15e09 --- /dev/null +++ b/test/driver.js @@ -0,0 +1,228 @@ +/* + * A Test Driver for PDF.js + */ + + +var appPath, browser, canvas, currentTaskIdx, manifest, stdout; + +function queryParams() { + var qs = window.location.search.substring(1); + var kvs = qs.split("&"); + var params = { }; + for (var i = 0; i < kvs.length; ++i) { + var kv = kvs[i].split("="); + params[unescape(kv[0])] = unescape(kv[1]); + } + return params; +} + +function load() { + var params = queryParams(); + browser = params.browser; + manifestFile = params.manifestFile; + appPath = params.path; + + canvas = document.createElement("canvas"); + canvas.mozOpaque = true; + stdout = document.getElementById("stdout"); + + log("load...\n"); + + log("Harness thinks this browser is '"+ browser + "' with path " + appPath + "\n"); + log("Fetching manifest "+ manifestFile +"..."); + + var r = new XMLHttpRequest(); + r.open("GET", manifestFile, false); + r.onreadystatechange = function(e) { + if (r.readyState == 4) { + log("done\n"); + manifest = JSON.parse(r.responseText); + currentTaskIdx = 0, nextTask(); + } + }; + r.send(null); +} +window.onload = load; + +function nextTask() { + if (currentTaskIdx == manifest.length) { + return done(); + } + var task = manifest[currentTaskIdx]; + task.round = 0; + + log("Loading file "+ task.file +"\n"); + + var r = new XMLHttpRequest(); + r.open("GET", task.file); + r.mozResponseType = r.responseType = "arraybuffer"; + r.onreadystatechange = function() { + if (r.readyState == 4) { + var data = r.mozResponseArrayBuffer || r.mozResponse || + r.responseArrayBuffer || r.response; + + try { + task.pdfDoc = new PDFDoc(new Stream(data)); + } catch(e) { + failure = 'load PDF doc: '+ e.toString(); + } + + task.pageNum = 1, nextPage(task); + } + }; + r.send(null); +} + +function isLastPage(task) { + return (task.pdfDoc && (task.pageNum > task.pdfDoc.numPages)); +} + +function nextPage(task) { + if (isLastPage(task)) { + if (++task.round < task.rounds) { + log(" Round "+ (1 + task.round) +"\n"); + task.pageNum = 1; + } else { + ++currentTaskIdx, nextTask(); + return; + } + } + + var failure = ''; + log(" loading page "+ task.pageNum +"... "); + + var ctx = canvas.getContext("2d"); + var fonts = []; + var gfx = null; + var page = null; + + try { + gfx = new CanvasGraphics(ctx); + page = task.pdfDoc.getPage(task.pageNum); + page.compile(gfx, fonts); + } catch(e) { + failure = 'compile: '+ e.toString(); + } + + if (!failure) { + try { + var pdfToCssUnitsCoef = 96.0 / 72.0; + // using mediaBox for the canvas size + var pageWidth = (page.mediaBox[2] - page.mediaBox[0]); + var pageHeight = (page.mediaBox[3] - page.mediaBox[1]); + canvas.width = pageWidth * pdfToCssUnitsCoef; + canvas.height = pageHeight * pdfToCssUnitsCoef; + clear(ctx); + } catch(e) { + failure = 'page setup: '+ e.toString(); + } + } + + if (!failure) { + try { + FontLoader.bind(fonts, function() { + snapshotCurrentPage(gfx, page, task, failure); + }); + } catch(e) { + failure = 'fonts: '+ e.toString(); + } + } + + if (failure) { + // Skip right to snapshotting if there was a failure, since the + // fonts might be in an inconsistent state. + snapshotCurrentPage(gfx, page, task, failure); + } +} + +function snapshotCurrentPage(gfx, page, task, failure) { + log("done, snapshotting... "); + + if (!failure) { + try { + page.display(gfx); + } catch(e) { + failure = 'render: '+ e.toString(); + } + } + + sendTaskResult(canvas.toDataURL("image/png"), task, failure); + log("done"+ (failure ? " (failed!)" : "") +"\n"); + + // Set up the next request + backoff = (inFlightRequests > 0) ? inFlightRequests * 10 : 0; + setTimeout(function() { + ++task.pageNum, nextPage(task); + }, + backoff + ); +} + +function sendQuitRequest() { + var r = new XMLHttpRequest(); + r.open("POST", "/tellMeToQuit?path=" + escape(appPath), false); + r.send(""); +} + +function quitApp() { + log("Done!"); + document.body.innerHTML = "Tests are finished.

CLOSE ME!

"; + if (window.SpecialPowers) { + SpecialPowers.quitApplication(); + } else { + sendQuitRequest(); + window.close(); + } +} + +function done() { + if (inFlightRequests > 0) { + document.getElementById("inFlightCount").innerHTML = inFlightRequests; + setTimeout(done, 100); + } else { + setTimeout(quitApp, 100); + } +} + +var inFlightRequests = 0; +function sendTaskResult(snapshot, task, failure) { + var result = { browser: browser, + id: task.id, + numPages: task.pdfDoc.numPages, + failure: failure, + file: task.file, + round: task.round, + page: task.pageNum, + snapshot: snapshot }; + + var r = new XMLHttpRequest(); + // (The POST URI is ignored atm.) + r.open("POST", "/submit_task_results", true); + r.setRequestHeader("Content-Type", "application/json"); + r.onreadystatechange = function(e) { + if (r.readyState == 4) { + inFlightRequests--; + } + } + document.getElementById("inFlightCount").innerHTML = inFlightRequests++; + r.send(JSON.stringify(result)); +} + +function clear(ctx) { + ctx.save(); + ctx.fillStyle = "rgb(255, 255, 255)"; + ctx.fillRect(0, 0, canvas.width, canvas.height); + ctx.restore(); +} + +/* Auto-scroll if the scrollbar is near the bottom, otherwise do nothing. */ +function checkScrolling() { + if ((stdout.scrollHeight - stdout.scrollTop) <= stdout.offsetHeight) { + stdout.scrollTop = stdout.scrollHeight; + } +} + +function log(str) { + stdout.innerHTML += str; + checkScrolling(); +} \ No newline at end of file diff --git a/test/test_slave.html b/test/test_slave.html index 3180418fa..f6d1f7f48 100644 --- a/test/test_slave.html +++ b/test/test_slave.html @@ -6,222 +6,7 @@ - + From 1aa0b390b9fb252f462925bdffb234b1d6a828c5 Mon Sep 17 00:00:00 2001 From: Rob Sayre Date: Mon, 4 Jul 2011 14:25:33 -0700 Subject: [PATCH 03/15] Make sure to guard against load errors. --- test/driver.js | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/test/driver.js b/test/driver.js index e7fb15e09..baa7358fd 100644 --- a/test/driver.js +++ b/test/driver.js @@ -57,6 +57,7 @@ function nextTask() { r.open("GET", task.file); r.mozResponseType = r.responseType = "arraybuffer"; r.onreadystatechange = function() { + var failure; if (r.readyState == 4) { var data = r.mozResponseArrayBuffer || r.mozResponse || r.responseArrayBuffer || r.response; @@ -67,7 +68,7 @@ function nextTask() { failure = 'load PDF doc: '+ e.toString(); } - task.pageNum = 1, nextPage(task); + task.pageNum = 1, nextPage(task, failure); } }; r.send(null); @@ -77,7 +78,7 @@ function isLastPage(task) { return (task.pdfDoc && (task.pageNum > task.pdfDoc.numPages)); } -function nextPage(task) { +function nextPage(task, loadError) { if (isLastPage(task)) { if (++task.round < task.rounds) { log(" Round "+ (1 + task.round) +"\n"); @@ -88,20 +89,24 @@ function nextPage(task) { } } - var failure = ''; - log(" loading page "+ task.pageNum +"... "); + var failure = loadError || ''; - var ctx = canvas.getContext("2d"); - var fonts = []; + var ctx = null; + var fonts; var gfx = null; var page = null; - try { - gfx = new CanvasGraphics(ctx); - page = task.pdfDoc.getPage(task.pageNum); - page.compile(gfx, fonts); - } catch(e) { - failure = 'compile: '+ e.toString(); + if (!failure) { + log(" loading page "+ task.pageNum +"... "); + ctx = canvas.getContext("2d"); + fonts = []; + try { + gfx = new CanvasGraphics(ctx); + page = task.pdfDoc.getPage(task.pageNum); + page.compile(gfx, fonts); + } catch(e) { + failure = 'compile: '+ e.toString(); + } } if (!failure) { From d4f49c05c5f4fbaeda24ec5b7b590ce36434a74d Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Mon, 4 Jul 2011 17:39:29 -0400 Subject: [PATCH 04/15] fix another binary-mode issue --- pdf.js | 1 + test/test.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/pdf.js b/pdf.js index 814c99f75..48fa004e6 100644 --- a/pdf.js +++ b/pdf.js @@ -2971,6 +2971,7 @@ var Catalog = (function() { var PDFDoc = (function() { function constructor(stream) { + assertWellFormed(stream.length > 0, "stream must have data"); this.stream = stream; this.setup(); } diff --git a/test/test.py b/test/test.py index 367347e88..00b87f786 100644 --- a/test/test.py +++ b/test/test.py @@ -275,7 +275,7 @@ def downloadLinkedPDFs(manifestList): sys.stdout.flush() response = urllib2.urlopen(link) - with open(f, 'w') as out: + with open(f, 'wb') as out: out.write(response.read()) print 'done' From fe09c1852c853606e956cb47419d6fc9da0a4ea4 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Mon, 4 Jul 2011 18:21:13 -0400 Subject: [PATCH 05/15] handle font names with comments (fix fix of hack hack) --- fonts.js | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/fonts.js b/fonts.js index 12d7ce82e..735213f5b 100644 --- a/fonts.js +++ b/fonts.js @@ -218,12 +218,7 @@ var FontLoader = { window.addEventListener( "message", function(e) { - var fontNames = e.data; - // Firefox 5 doesn't parse the JSON here. Welcome to the - // Wonderful Web World. - if ("string" == typeof(fontNames)) { - fontNames = fontNames.split(","); - } + var fontNames = JSON.parse(e.data); for (var i = 0; i < fontNames.length; ++i) { var font = Fonts.lookup(fontNames[i]); font.loading = false; @@ -251,7 +246,7 @@ var FontLoader = { } src += ' var fontNames=['+ fontNamesArray +'];\n'; src += ' window.onload = function () {\n' - src += ' top.postMessage(fontNames, "*");\n'; + src += ' top.postMessage(JSON.stringify(fontNames), "*");\n'; src += ' }'; src += ''; for (var i = 0; i < names.length; ++i) { From 122d168b51b92dd0b682c69a2acb14e97a5c4b91 Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Mon, 4 Jul 2011 23:28:44 -0400 Subject: [PATCH 06/15] fix some bugs --- fonts.js | 4 ++-- pdf.js | 2 +- test/driver.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/fonts.js b/fonts.js index 735213f5b..47aeabc3f 100644 --- a/fonts.js +++ b/fonts.js @@ -1807,8 +1807,8 @@ CFF.prototype = { var data = "\x8b\x14" + // defaultWidth "\x8b\x15" + // nominalWidth - self.encodeNumber(properties.stdHW) + "\x0a" + // StdHW - self.encodeNumber(properties.stdVW) + "\x0b"; // StdVW + self.encodeNumber(properties.stdHW || 0) + "\x0a" + // StdHW + self.encodeNumber(properties.stdVW || 0) + "\x0b"; // StdVW var stemH = properties.stemSnapH; for (var i = 0; i < stemH.length; i++) diff --git a/pdf.js b/pdf.js index 48fa004e6..5644bf036 100644 --- a/pdf.js +++ b/pdf.js @@ -3875,7 +3875,7 @@ var CanvasGraphics = (function() { this.ctx.translate(this.current.x, -1 * this.current.y); var font = Fonts.lookup(this.current.fontName); - if (font) + if (font && font.properties.textMatrix) this.ctx.transform.apply(this.ctx, font.properties.textMatrix); this.ctx.fillText(text, 0, 0); diff --git a/test/driver.js b/test/driver.js index baa7358fd..b4c2c64e0 100644 --- a/test/driver.js +++ b/test/driver.js @@ -152,7 +152,7 @@ function snapshotCurrentPage(gfx, page, task, failure) { } sendTaskResult(canvas.toDataURL("image/png"), task, failure); - log("done"+ (failure ? " (failed!)" : "") +"\n"); + log("done"+ (failure ? " (failed!: "+ failure +")" : "") +"\n"); // Set up the next request backoff = (inFlightRequests > 0) ? inFlightRequests * 10 : 0; From 2dc1ff98ace437f32f41a560f8772e47aa2ebb4f Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Tue, 5 Jul 2011 00:02:09 -0400 Subject: [PATCH 07/15] built-in fonts are not cached --- fonts.js | 15 +++++++++------ viewer.js | 4 +++- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/fonts.js b/fonts.js index 47aeabc3f..8701f8e5f 100644 --- a/fonts.js +++ b/fonts.js @@ -70,11 +70,14 @@ var Fonts = (function Fonts() { return fonts[fontName]; }, setActive: function fonts_setActive(fontName, size) { - current = fonts[fontName]; - charsCache = current.charsCache; - var sizes = current.sizes; - if (!(measureCache = sizes[size])) - measureCache = sizes[size] = Object.create(null); + // |current| can be null is fontName is a built-in font + // (e.g. "sans-serif") + if ((current = fonts[fontName])) { + charsCache = current.charsCache; + var sizes = current.sizes; + if (!(measureCache = sizes[size])) + measureCache = sizes[size] = Object.create(null); + } ctx.font = (size * kScalePrecision) + 'px "' + fontName + '"'; }, charsToUnicode: function fonts_chars2Unicode(chars) { @@ -87,7 +90,7 @@ var Fonts = (function Fonts() { return str; // translate the string using the font's encoding - var encoding = current.properties.encoding; + var encoding = current ? current.properties.encoding : null; if (!encoding) return chars; diff --git a/viewer.js b/viewer.js index 4071151aa..6702a6735 100644 --- a/viewer.js +++ b/viewer.js @@ -91,7 +91,9 @@ function displayPage(num) { infoDisplay.innerHTML = "Time to load/compile/fonts/render: "+ (t1 - t0) + "/" + (t2 - t1) + "/" + (t3 - t2) + "/" + (t4 - t3) + " ms"; } - FontLoader.bind(fonts, displayPage); + // Always defer call to displayPage() to work around bug in + // Firefox error reporting from XHR callbacks. + FontLoader.bind(fonts, function () { setTimeout(displayPage, 0); }); } function nextPage() { From 2e83b0cc0d682ab2f7d6c7d6388da312c15f5e95 Mon Sep 17 00:00:00 2001 From: sbarman Date: Tue, 5 Jul 2011 11:10:14 -0500 Subject: [PATCH 08/15] Fixes to parser for the test pdf in www.unicode.org/charts --- pdf.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pdf.js b/pdf.js index 5644bf036..c34bc76ed 100644 --- a/pdf.js +++ b/pdf.js @@ -2236,6 +2236,9 @@ var Lexer = (function() { var stream = this.stream; var ch; while (true) { + if (!stream.getChar) + log("bad stream"); + if (!(ch = stream.getChar())) return EOF; if (comment) { @@ -2842,7 +2845,7 @@ var Page = (function() { constructor.prototype = { getPageProp: function(key) { - return this.pageDict.get(key); + return this.xref.fetchIfRef(this.pageDict.get(key)); }, inheritPageProp: function(key) { var dict = this.pageDict; @@ -3579,6 +3582,7 @@ var CanvasGraphics = (function() { }, compile: function(stream, xref, resources, fonts) { + resources = xref.fetchIfRef(resources) || new Dict(); var xobjs = xref.fetchIfRef(resources.get("XObject")) || new Dict(); var parser = new Parser(new Lexer(stream), false); From 28a01646bb40328c29593e0d221e3e9817685c86 Mon Sep 17 00:00:00 2001 From: sbarman Date: Tue, 5 Jul 2011 11:13:53 -0500 Subject: [PATCH 09/15] cleanup --- pdf.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/pdf.js b/pdf.js index c34bc76ed..ea28ca647 100644 --- a/pdf.js +++ b/pdf.js @@ -2236,9 +2236,6 @@ var Lexer = (function() { var stream = this.stream; var ch; while (true) { - if (!stream.getChar) - log("bad stream"); - if (!(ch = stream.getChar())) return EOF; if (comment) { From 7d3e08eefd57df07a86910d88f04f14e95e4ce78 Mon Sep 17 00:00:00 2001 From: sbarman Date: Tue, 5 Jul 2011 11:44:26 -0500 Subject: [PATCH 10/15] bug with length of lookup table --- pdf.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pdf.js b/pdf.js index 5644bf036..5743876d6 100644 --- a/pdf.js +++ b/pdf.js @@ -4452,7 +4452,7 @@ var ColorSpace = (function() { break; case "Indexed": var base = ColorSpace.parse(cs[1], xref, res); - var hiVal = cs[2]; + var hiVal = cs[2] + 1; var lookup = xref.fetchIfRef(cs[3]); return new IndexedCS(base, hiVal, lookup); case "Lab": From e8f98f4e16ba01976a81f21dc0426b8d6ae616aa Mon Sep 17 00:00:00 2001 From: Chris Jones Date: Tue, 5 Jul 2011 13:21:28 -0400 Subject: [PATCH 11/15] add unicode test --- test/pdfs/shavian.pdf.link | 1 + test/test_manifest.json | 6 ++++++ 2 files changed, 7 insertions(+) create mode 100644 test/pdfs/shavian.pdf.link diff --git a/test/pdfs/shavian.pdf.link b/test/pdfs/shavian.pdf.link new file mode 100644 index 000000000..42c438644 --- /dev/null +++ b/test/pdfs/shavian.pdf.link @@ -0,0 +1 @@ +http://www.unicode.org/charts/PDF/U10450.pdf \ No newline at end of file diff --git a/test/test_manifest.json b/test/test_manifest.json index 06787925f..4302e1f6e 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -26,6 +26,12 @@ "rounds": 1, "type": "load" }, + { "id": "shavian-load", + "file": "pdfs/shavian.pdf", + "link": true, + "rounds": 1, + "type": "load" + }, { "id": "sizes", "file": "pdfs/sizes.pdf", "rounds": 1, From 7f5c7a3130e1f888edefe04c7f4ddffb033f75ee Mon Sep 17 00:00:00 2001 From: Rob Sayre Date: Tue, 5 Jul 2011 10:53:57 -0700 Subject: [PATCH 12/15] Add Makefile. Move some files around to make building the website easier. --- Makefile | 154 ++++++++++++++++++ .../compressed.tracemonkey-pldi-09.pdf | Bin {images => web/images}/buttons.png | Bin {images => web/images}/source/Buttons.psd.zip | Bin .../images}/source/FileButton.psd.zip | Bin web/index.html.template | 88 ++++++++++ .../multi_page_viewer.css | 0 .../multi_page_viewer.html | 0 .../multi_page_viewer.js | 0 viewer.css => web/viewer.css | 0 viewer.html => web/viewer.html | 0 viewer.js => web/viewer.js | 0 viewer_worker.html => web/viewer_worker.html | 0 13 files changed, 242 insertions(+) create mode 100644 Makefile rename compressed.tracemonkey-pldi-09.pdf => web/compressed.tracemonkey-pldi-09.pdf (100%) rename {images => web/images}/buttons.png (100%) rename {images => web/images}/source/Buttons.psd.zip (100%) rename {images => web/images}/source/FileButton.psd.zip (100%) create mode 100644 web/index.html.template rename multi_page_viewer.css => web/multi_page_viewer.css (100%) rename multi_page_viewer.html => web/multi_page_viewer.html (100%) rename multi_page_viewer.js => web/multi_page_viewer.js (100%) rename viewer.css => web/viewer.css (100%) rename viewer.html => web/viewer.html (100%) rename viewer.js => web/viewer.js (100%) rename viewer_worker.html => web/viewer_worker.html (100%) diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..da18e5b32 --- /dev/null +++ b/Makefile @@ -0,0 +1,154 @@ +REPO = git@github.com:andreasgal/pdf.js.git +BUILD_DIR := build +DEFAULT_BROWSERS := test/resources/browser_manifests/browser_manifest.json +DEFAULT_TESTS := test/test_manifest.json + +# JS files needed for pdf.js. +# This list doesn't account for the 'worker' directory. +PDF_JS_FILES = \ + pdf.js \ + crypto.js \ + fonts.js \ + glyphlist.js \ + $(NULL) + +# not sure what to do for all yet +all: help + +test: shell-test browser-test + +# make browser-test +# +# This target runs in-browser tests using two primary arguments: a +# test manifest file, and a browser manifest file. Both are simple +# JSON formats, and examples can be found in the test/ directory. The +# target will inspect the environment for the PDF_TESTS and +# PDF_BROWSERS variables, and use those if found. Otherwise, the +# defaults at the top of this file are used. +ifeq ($(PDF_TESTS),) +PDF_TESTS := $(DEFAULT_TESTS) +endif +ifeq ($(PDF_BROWSERS),) +PDF_BROWSERS := $(DEFAULT_BROWSERS) +endif + + +browser-test: + @if [ ! "$(PDF_BROWSERS)" ]; then \ + echo "Browser manifest file $(PDF_BROWSERS) does not exist."; \ + echo "Try copying one of the examples" \ + "in test/resources/browser_manifests/"; \ + exit 1; \ + fi; + + cd test; \ + python test.py --reftest \ + --browserManifestFile=$(abspath $(PDF_BROWSERS)) \ + --manifestFile=$(abspath $(PDF_TESTS)) + +# make shell-test +# +# This target runs all of the tests that can be run in a JS shell. +# The shell used is taken from the JS_SHELL environment variable. If +# that veriable is not defined, the script will attempt to use the copy +# of Rhino that comes with the Closure compiler used for producing the +# website. +SHELL_TARGET = $(NULL) +ifeq ($(JS_SHELL),) +JS_SHELL := "java -cp $(BUILD_DIR)/compiler.jar" +JS_SHELL += "com.google.javascript.jscomp.mozilla.rhino.tools.shell.Main" +SHELL_TARGET = compiler +endif + +shell-test: shell-msg $(SHELL_TARGET) font-test +shell-msg: +ifeq ($(SHELL_TARGET), compiler) + @echo "No JS_SHELL env variable present." + @echo "The default is to find a copy of Rhino and try that." +endif + @echo "JS shell command is: $(JS_SHELL)" + +font-test: + @echo "font test stub." + +# make lint +# +# This target runs the Closure Linter on most of our JS files. +# To install gjslint, see: +# +# +SRC_DIRS := . utils worker web +GJSLINT_FILES = $(foreach DIR,$(SRC_DIRS),$(wildcard $(DIR)/*.js)) +lint: + gjslint $(GJSLINT_FILES) + +# make web +# +# This target produces the website for the project, by checking out +# the gh-pages branch underneath the build directory, and then move +# the various viewer files into place. +# +# TODO: Use the Closure compiler to optimize the pdf.js files. +# +GH_PAGES = $(BUILD_DIR)/gh-pages +web: | compiler pages-repo \ + $(addprefix $(GH_PAGES)/, $(PDF_JS_FILES)) \ + $(addprefix $(GH_PAGES)/, $(wildcard web/*.*)) \ + $(addprefix $(GH_PAGES)/, $(wildcard web/images/*.*)) + + @cp $(GH_PAGES)/web/index.html.template $(GH_PAGES)/index.html; + @cd $(GH_PAGES); git add -A; + @echo "Website built in $(GH_PAGES)" + +# make pages-repo +# +# This target clones the gh-pages repo into the build directory. It +# deletes the current contents of the repo, since we overwrite +# everything with data from the master repo. The 'make web' target +# then uses 'git add -A' to track additions, modifications, moves, +# and deletions. +pages-repo: | $(BUILD_DIR) + @if [ ! -d "$(GH_PAGES)" ]; then \ + git clone -b gh-pages $(REPO) $(GH_PAGES); \ + rm -rf $(GH_PAGES)/*; \ + fi; + @mkdir -p $(GH_PAGES)/web; + @mkdir -p $(GH_PAGES)/web/images; + +$(GH_PAGES)/%.js: %.js + @cp $< $@ + +$(GH_PAGES)/web/%: web/% + @cp $< $@ + +$(GH_PAGES)/web/images/%: web/images/% + @cp $< $@ + +# make compiler +# +# This target downloads the Closure compiler, and places it in the +# build directory. This target is also useful when the user doesn't +# have a JS shell available--we can have them use the Rhino shell that +# comes with Closure. +COMPILER_URL = http://closure-compiler.googlecode.com/files/compiler-latest.zip + +compiler: $(BUILD_DIR)/compiler.zip +$(BUILD_DIR)/compiler.zip: | $(BUILD_DIR) + curl $(COMPILER_URL) > $(BUILD_DIR)/compiler.zip; + cd $(BUILD_DIR); unzip compiler.zip compiler.jar; + +# Make sure there's a build directory. +$(BUILD_DIR): + mkdir -p $(BUILD_DIR) + +clean: + rm -rf $(BUILD_DIR) + +# make help +# +# This target just prints out a message to read these comments. :) +help: + @echo "Read the comments in the Makefile for guidance."; + +.PHONY: all test browser-test font-test shell-test \ + shell-msg lint clean web compiler help \ No newline at end of file diff --git a/compressed.tracemonkey-pldi-09.pdf b/web/compressed.tracemonkey-pldi-09.pdf similarity index 100% rename from compressed.tracemonkey-pldi-09.pdf rename to web/compressed.tracemonkey-pldi-09.pdf diff --git a/images/buttons.png b/web/images/buttons.png similarity index 100% rename from images/buttons.png rename to web/images/buttons.png diff --git a/images/source/Buttons.psd.zip b/web/images/source/Buttons.psd.zip similarity index 100% rename from images/source/Buttons.psd.zip rename to web/images/source/Buttons.psd.zip diff --git a/images/source/FileButton.psd.zip b/web/images/source/FileButton.psd.zip similarity index 100% rename from images/source/FileButton.psd.zip rename to web/images/source/FileButton.psd.zip diff --git a/web/index.html.template b/web/index.html.template new file mode 100644 index 000000000..c3086f078 --- /dev/null +++ b/web/index.html.template @@ -0,0 +1,88 @@ + + + + + + andreasgal/pdf.js @ GitHub + + + + + + Fork me on GitHub + +
+ +
+ + + + +
+ +

pdf.js + by andreasgal

+ +
+ PDF Reader in JavaScript +
+ +

Try it out!

+

Live demo lives here.

+ +

Authors

+

Vivien Nicolas (21@vingtetun.org) +
Andreas Gal (andreas.gal@gmail.com) +
Soumya Deb (debloper@gmail.com) +
Chris Jones (jones.chris.g@gmail.com) +
Justin D'Arcangelo (justindarc@gmail.com) +
sbarman (sbarman@eecs.berkeley.edu) +
+

+

Contact

+

(andreas.gal@gmail.com) +

+ + +

Download

+

+ You can download this project in either + zip or + tar formats. +

+

You can also clone the project with Git + by running: +

$ git clone git://github.com/andreasgal/pdf.js
+

+ + + +
+ + + + diff --git a/multi_page_viewer.css b/web/multi_page_viewer.css similarity index 100% rename from multi_page_viewer.css rename to web/multi_page_viewer.css diff --git a/multi_page_viewer.html b/web/multi_page_viewer.html similarity index 100% rename from multi_page_viewer.html rename to web/multi_page_viewer.html diff --git a/multi_page_viewer.js b/web/multi_page_viewer.js similarity index 100% rename from multi_page_viewer.js rename to web/multi_page_viewer.js diff --git a/viewer.css b/web/viewer.css similarity index 100% rename from viewer.css rename to web/viewer.css diff --git a/viewer.html b/web/viewer.html similarity index 100% rename from viewer.html rename to web/viewer.html diff --git a/viewer.js b/web/viewer.js similarity index 100% rename from viewer.js rename to web/viewer.js diff --git a/viewer_worker.html b/web/viewer_worker.html similarity index 100% rename from viewer_worker.html rename to web/viewer_worker.html From 54bfa1d7e9fad873fc91ed984d8ded7e70acc760 Mon Sep 17 00:00:00 2001 From: Rob Sayre Date: Tue, 5 Jul 2011 10:55:01 -0700 Subject: [PATCH 13/15] Add newline to end of Makefile. --- Makefile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index da18e5b32..c4ece46f6 100644 --- a/Makefile +++ b/Makefile @@ -32,7 +32,6 @@ ifeq ($(PDF_BROWSERS),) PDF_BROWSERS := $(DEFAULT_BROWSERS) endif - browser-test: @if [ ! "$(PDF_BROWSERS)" ]; then \ echo "Browser manifest file $(PDF_BROWSERS) does not exist."; \ @@ -98,7 +97,7 @@ web: | compiler pages-repo \ @cp $(GH_PAGES)/web/index.html.template $(GH_PAGES)/index.html; @cd $(GH_PAGES); git add -A; - @echo "Website built in $(GH_PAGES)" + @echo "Website built in $(GH_PAGES)." # make pages-repo # @@ -151,4 +150,4 @@ help: @echo "Read the comments in the Makefile for guidance."; .PHONY: all test browser-test font-test shell-test \ - shell-msg lint clean web compiler help \ No newline at end of file + shell-msg lint clean web compiler help From 45303847697402eecd888b2ea1d41759d8f68fcd Mon Sep 17 00:00:00 2001 From: Rob Sayre Date: Tue, 5 Jul 2011 13:51:02 -0700 Subject: [PATCH 14/15] Add a make server target, fix paths to scripts. --- Makefile | 9 ++++++++- test/test.py | 22 +++++++++++++--------- web/multi_page_viewer.html | 8 ++++---- web/viewer.html | 9 ++++----- web/viewer_worker.html | 8 ++++---- 5 files changed, 33 insertions(+), 23 deletions(-) diff --git a/Makefile b/Makefile index c4ece46f6..fa2cf816e 100644 --- a/Makefile +++ b/Makefile @@ -15,6 +15,13 @@ PDF_JS_FILES = \ # not sure what to do for all yet all: help +# make server +# +# 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; + test: shell-test browser-test # make browser-test @@ -150,4 +157,4 @@ help: @echo "Read the comments in the Makefile for guidance."; .PHONY: all test browser-test font-test shell-test \ - shell-msg lint clean web compiler help + shell-msg lint clean web compiler help server diff --git a/test/test.py b/test/test.py index 00b87f786..3f007a21a 100644 --- a/test/test.py +++ b/test/test.py @@ -17,7 +17,6 @@ TMPDIR = 'tmp' VERBOSE = False SERVER_HOST = "localhost" -SERVER_PORT = 8080 class TestOptions(OptionParser): def __init__(self, **kwargs): @@ -34,6 +33,8 @@ class TestOptions(OptionParser): self.add_option("--reftest", action="store_true", dest="reftest", help="Automatically start reftest showing comparison test failures, if there are any.", default=False) + self.add_option("--port", action="store", dest="port", type="int", + help="The port the HTTP server should listen on.", default=8080) self.set_usage(USAGE_EXAMPLE) def verifyOptions(self, options): @@ -44,7 +45,7 @@ class TestOptions(OptionParser): if options.browser and options.browserManifestFile: print "Warning: ignoring browser argument since manifest file was also supplied" if not options.browser and not options.browserManifestFile: - print "No browser arguments supplied, so just starting server on port %s." % SERVER_PORT + print "Starting server on port %s." % options.port return options def prompt(question): @@ -325,7 +326,7 @@ def startBrowsers(browsers, options): for b in browsers: b.setup() print 'Launching', b.name - host = 'http://%s:%s' % (SERVER_HOST, SERVER_PORT) + host = 'http://%s:%s' % (SERVER_HOST, options.port) path = '/test/test_slave.html?' qs = 'browser='+ urllib.quote(b.name) +'&manifestFile='+ urllib.quote(options.manifestFile) qs += '&path=' + b.path @@ -482,8 +483,8 @@ def maybeUpdateRefImages(options, browser): print 'done' -def startReftest(browser): - url = "http://%s:%s" % (SERVER_HOST, SERVER_PORT) +def startReftest(browser, options): + url = "http://%s:%s" % (SERVER_HOST, options.port) url += "/test/resources/reftest-analyzer.xhtml" url += "#web=/test/eq.log" try: @@ -511,7 +512,7 @@ def runTests(options, browsers): maybeUpdateRefImages(options, browsers[0]) elif options.reftest and State.numEqFailures > 0: print "\nStarting reftest harness to examine %d eq test failures." % State.numEqFailures - startReftest(browsers[0]) + startReftest(browsers[0], options) def main(): optionParser = TestOptions() @@ -520,7 +521,7 @@ def main(): if options == None: sys.exit(1) - httpd = TestServer((SERVER_HOST, SERVER_PORT), PDFTestHandler) + httpd = TestServer((SERVER_HOST, options.port), PDFTestHandler) httpd_thread = threading.Thread(target=httpd.serve_forever) httpd_thread.setDaemon(True) httpd_thread.start() @@ -531,8 +532,11 @@ def main(): else: # just run the server print "Running HTTP server. Press Ctrl-C to quit." - while True: - time.sleep(1) + try: + while True: + time.sleep(1) + except (KeyboardInterrupt): + print "\nExiting." if __name__ == '__main__': main() diff --git a/web/multi_page_viewer.html b/web/multi_page_viewer.html index df71d6690..841d2dba9 100644 --- a/web/multi_page_viewer.html +++ b/web/multi_page_viewer.html @@ -4,10 +4,10 @@ pdf.js Multi-Page Viewer - - - - + + + + diff --git a/web/viewer.html b/web/viewer.html index c600547f0..a5b553c1f 100644 --- a/web/viewer.html +++ b/web/viewer.html @@ -4,11 +4,10 @@ - - - - - + + + + diff --git a/web/viewer_worker.html b/web/viewer_worker.html index 89fb8a087..21a5be3ca 100644 --- a/web/viewer_worker.html +++ b/web/viewer_worker.html @@ -1,10 +1,10 @@ Simple pdf.js page worker viewer - - - - + + + +