From 802f664baa6ed8a7ea440fa060032975ca837586 Mon Sep 17 00:00:00 2001 From: Kalervo Kujala Date: Tue, 16 Aug 2011 22:17:46 +0300 Subject: [PATCH 1/7] Indent the driver.js correctly. --- test/driver.js | 216 +++++++++++++++++++++++++------------------------ 1 file changed, 109 insertions(+), 107 deletions(-) diff --git a/test/driver.js b/test/driver.js index 0601777a8..f12dcae23 100644 --- a/test/driver.js +++ b/test/driver.js @@ -10,137 +10,139 @@ 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; + 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; - var 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); + var params = queryParams(); + browser = params.browser; + var 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(); + 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() { + var failure; + 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, failure); } - 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() { - var failure; - 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, failure); - } - }; - r.send(null); + }; + r.send(null); } function isLastPage(task) { - return (!task.pdfDoc || (task.pageNum > task.pdfDoc.numPages)); + return (!task.pdfDoc || (task.pageNum > task.pdfDoc.numPages)); } function nextPage(task, loadError) { - if (isLastPage(task)) { - if (++task.round < task.rounds) { - log(' Round ' + (1 + task.round) + '\n'); - task.pageNum = 1; - } else { - ++currentTaskIdx, nextTask(); - return; - } + if (isLastPage(task)) { + if (++task.round < task.rounds) { + log(' Round ' + (1 + task.round) + '\n'); + task.pageNum = 1; + } else { + ++currentTaskIdx, nextTask(); + return; } + } - var failure = loadError || ''; - - var ctx = null; - var page = null; - if (!failure) { - try { - log(' loading page ' + task.pageNum + '/' + task.pdfDoc.numPages + - '... '); - ctx = canvas.getContext('2d'); - page = task.pdfDoc.getPage(task.pageNum); - - var pdfToCssUnitsCoef = 96.0 / 72.0; - // using mediaBox for the canvas size - var pageWidth = page.width; - var pageHeight = page.height; - canvas.width = pageWidth * pdfToCssUnitsCoef; - canvas.height = pageHeight * pdfToCssUnitsCoef; - clear(ctx); - - page.startRendering( - ctx, - function(e) { - snapshotCurrentPage(page, task, (!failure && e) ? - ('render : ' + e) : failure); - }); - } catch (e) { - failure = 'page setup : ' + e.toString(); + var failure = loadError || ''; + + var ctx = null; + var page = null; + if (!failure) { + try { + log(' loading page ' + task.pageNum + '/' + task.pdfDoc.numPages + + '... '); + ctx = canvas.getContext('2d'); + page = task.pdfDoc.getPage(task.pageNum); + + var pdfToCssUnitsCoef = 96.0 / 72.0; + // using mediaBox for the canvas size + var pageWidth = page.width; + var pageHeight = page.height; + canvas.width = pageWidth * pdfToCssUnitsCoef; + canvas.height = pageHeight * pdfToCssUnitsCoef; + clear(ctx); + + page.startRendering( + ctx, + function(e) { + snapshotCurrentPage(page, task, (!failure && e) ? + ('render : ' + e) : failure); } + ); + } catch (e) { + failure = 'page setup : ' + e.toString(); } + } - if (failure) { - // Skip right to snapshotting if there was a failure, since the - // fonts might be in an inconsistent state. - snapshotCurrentPage(page, task, failure); - } + if (failure) { + // Skip right to snapshotting if there was a failure, since the + // fonts might be in an inconsistent state. + snapshotCurrentPage(page, task, failure); + } } function snapshotCurrentPage(page, task, failure) { - log('done, snapshotting... '); + log('done, snapshotting... '); - sendTaskResult(canvas.toDataURL('image/png'), task, failure); - log('done' + (failure ? ' (failed !: ' + failure + ')' : '') + '\n'); + sendTaskResult(canvas.toDataURL('image/png'), task, failure); + log('done' + (failure ? ' (failed !: ' + failure + ')' : '') + '\n'); - // Set up the next request - var backoff = (inFlightRequests > 0) ? inFlightRequests * 10 : 0; - setTimeout(function() { - ++task.pageNum, nextPage(task); + // Set up the next request + var backoff = (inFlightRequests > 0) ? inFlightRequests * 10 : 0; + setTimeout( + function() { + ++task.pageNum, nextPage(task); }, backoff ); From 965193b38d789a389921d07ebcd924045f781fe7 Mon Sep 17 00:00:00 2001 From: Kalervo Kujala Date: Tue, 16 Aug 2011 23:08:55 +0300 Subject: [PATCH 2/7] Keep the results visible in test_slave.html before quitting. Currently the innerHTML is replaced with text: Tests are finished. CLOSE ME! Instead of replacing the innerHTML prepend that text to it. This way the user can still check the results of the test. --- test/driver.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/driver.js b/test/driver.js index f12dcae23..92fc00af1 100644 --- a/test/driver.js +++ b/test/driver.js @@ -156,7 +156,8 @@ function sendQuitRequest() { function quitApp() { log('Done !'); - document.body.innerHTML = 'Tests are finished.

CLOSE ME!

'; + document.body.innerHTML = 'Tests are finished.

CLOSE ME!

' + + document.body.innerHTML; if (window.SpecialPowers) { SpecialPowers.quitApplication(); } else { From 7cbdc982c51855f6c064a11f67ae0cf4f93c66be Mon Sep 17 00:00:00 2001 From: Kalervo Kujala Date: Wed, 17 Aug 2011 01:33:00 +0300 Subject: [PATCH 3/7] Report results properly to test.py from driver.js. If the PDFDoc creation failed in driver.js then that was not informed back to test.py. This lead to State.remaining being off by one. And that did not let the test to end as expected. Instead the test hung indefinitely. This change now reveals TEST-UNEXPECTED-FAIL which was hidden previously. --- test/driver.js | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/test/driver.js b/test/driver.js index 92fc00af1..716046c4b 100644 --- a/test/driver.js +++ b/test/driver.js @@ -80,10 +80,19 @@ function nextTask() { } function isLastPage(task) { - return (!task.pdfDoc || (task.pageNum > task.pdfDoc.numPages)); + return (task.pageNum > task.pdfDoc.numPages); } function nextPage(task, loadError) { + var failure = loadError || ''; + + if (!task.pdfDoc) { + sendTaskResult(canvas.toDataURL('image/png'), task, failure); + log('done' + (failure ? ' (failed !: ' + failure + ')' : '') + '\n'); + ++currentTaskIdx, nextTask(); + return; + } + if (isLastPage(task)) { if (++task.round < task.rounds) { log(' Round ' + (1 + task.round) + '\n'); @@ -94,15 +103,13 @@ function nextPage(task, loadError) { } } - var failure = loadError || ''; - - var ctx = null; var page = null; + if (!failure) { try { log(' loading page ' + task.pageNum + '/' + task.pdfDoc.numPages + '... '); - ctx = canvas.getContext('2d'); + var ctx = canvas.getContext('2d'); page = task.pdfDoc.getPage(task.pageNum); var pdfToCssUnitsCoef = 96.0 / 72.0; @@ -179,7 +186,7 @@ var inFlightRequests = 0; function sendTaskResult(snapshot, task, failure) { var result = { browser: browser, id: task.id, - numPages: task.pdfDoc.numPages, + numPages: task.pdfDoc ? task.pdfDoc.numPages : 0, failure: failure, file: task.file, round: task.round, From 2ef990059765e71ca2f35c7b6c90bc61e163d9ed Mon Sep 17 00:00:00 2001 From: sbarman Date: Tue, 16 Aug 2011 16:47:48 -0700 Subject: [PATCH 4/7] implemented curve2, partial fix for #325 --- pdf.js | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/pdf.js b/pdf.js index 79ae776f6..081abfd20 100644 --- a/pdf.js +++ b/pdf.js @@ -4,7 +4,7 @@ 'use strict'; var ERRORS = 0, WARNINGS = 1, TODOS = 5; -var verbosity = WARNINGS; +var verbosity = TODOS; function log(msg) { if (console && console.log) @@ -4137,6 +4137,9 @@ var CanvasExtraState = (function() { this.charSpacing = 0; this.wordSpacing = 0; this.textHScale = 1; + // Path variables + this.pathX = 0; + this.pathY = 0; // Color spaces this.fillColorSpaceObj = null; this.strokeColorSpaceObj = null; @@ -4276,18 +4279,39 @@ var CanvasGraphics = (function() { // Path moveTo: function(x, y) { this.ctx.moveTo(x, y); + + var current = this.current; + current.pathX = x; + current.pathY = y; }, lineTo: function(x, y) { this.ctx.lineTo(x, y); + + var current = this.current; + current.pathX = x; + current.pathY = y; }, curveTo: function(x1, y1, x2, y2, x3, y3) { this.ctx.bezierCurveTo(x1, y1, x2, y2, x3, y3); + + var current = this.current; + current.pathX = x3; + current.pathY = y3; }, curveTo2: function(x2, y2, x3, y3) { - TODO("'v' operator: need current point in gfx context"); + var current = this.current; + this.ctx.bezierCurveTo(current.pathX, current.pathY, x2, y2, x3, y3); +// TODO("'v' operator: need current point in gfx context"); + + current.pathX = x3; + current.pathY = y3; }, curveTo3: function(x1, y1, x3, y3) { this.curveTo(x1, y1, x3, y3, x3, y3); + + var current = this.current; + current.pathX = x3; + current.pathY = y3; }, closePath: function() { this.ctx.closePath(); From 8351877f1670c8b28f3a45ba4f002e41d4c7dda8 Mon Sep 17 00:00:00 2001 From: sbarman Date: Tue, 16 Aug 2011 16:49:26 -0700 Subject: [PATCH 5/7] cleanup --- pdf.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pdf.js b/pdf.js index 081abfd20..d9c1007bb 100644 --- a/pdf.js +++ b/pdf.js @@ -4,7 +4,7 @@ 'use strict'; var ERRORS = 0, WARNINGS = 1, TODOS = 5; -var verbosity = TODOS; +var verbosity = WARNINGS; function log(msg) { if (console && console.log) @@ -4301,7 +4301,6 @@ var CanvasGraphics = (function() { curveTo2: function(x2, y2, x3, y3) { var current = this.current; this.ctx.bezierCurveTo(current.pathX, current.pathY, x2, y2, x3, y3); -// TODO("'v' operator: need current point in gfx context"); current.pathX = x3; current.pathY = y3; From 7ae84533c60844aab6584608a4ea30bfc2f27513 Mon Sep 17 00:00:00 2001 From: sbarman Date: Tue, 16 Aug 2011 18:15:20 -0700 Subject: [PATCH 6/7] added stiched functions --- pdf.js | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/pdf.js b/pdf.js index d9c1007bb..45f5484f6 100644 --- a/pdf.js +++ b/pdf.js @@ -5727,7 +5727,7 @@ var PDFFunction = (function() { if (!typeFn) error('Unknown type of function'); - typeFn.call(this, fn, dict); + typeFn.call(this, fn, dict, xref); }; constructor.prototype = { @@ -5872,9 +5872,58 @@ var PDFFunction = (function() { return out; } }, - constructStiched: function() { - TODO('unhandled type of function'); - this.func = function() { return [255, 105, 180]; } + constructStiched: function(fn, dict, xref) { + var domain = dict.get('Domain'); + var range = dict.get('Range'); + + if (!domain) + error('No domain'); + + var inputSize = domain.length / 2; + if (inputSize != 1) + error('Bad domain for stiched function'); + + var fnRefs = dict.get('Functions'); + var fns = []; + for (var i = 0, ii = fnRefs.length; i < ii; ++i) + fns.push(new PDFFunction(xref, xref.fetchIfRef(fnRefs[i]))); + + var bounds = dict.get('Bounds'); + var encode = dict.get('Encode'); + + this.func = function(args) { + var clip = function(v, min, max) { + if (v > max) + v = max; + else if (v < min) + v = min; + return v; + } + + // clip to domain + var v = clip(args[0], domain[0], domain[1]); + // calulate which bound the value is in + for (var i = 0, ii = bounds.length; i < ii; ++i) { + if (v < bounds[i]) + break; + } + + // encode value into domain of function + var dmin = domain[0]; + if (i > 0) + dmin = bounds[i - 1]; + var dmax = domain[1]; + if (i < bounds.length) + dmax = bounds[i]; + + var rmin = encode[2 * i]; + var rmax = encode[2 * i + 1]; + + var v2 = rmin + (v - dmin) * (rmax - rmin) / (dmax - dmin); + + // call the appropropriate function + return fns[i].func([v2]); + } }, constructPostScript: function() { TODO('unhandled type of function'); From a7353ad737ad51593e1a00b7bbefffc39f8cf2fc Mon Sep 17 00:00:00 2001 From: sbarman Date: Wed, 17 Aug 2011 09:22:54 -0700 Subject: [PATCH 7/7] combined pathX/Y with x/y and wrote setCurrentPoint function --- pdf.js | 35 +++++++++++------------------------ 1 file changed, 11 insertions(+), 24 deletions(-) diff --git a/pdf.js b/pdf.js index 45f5484f6..2afed5f6b 100644 --- a/pdf.js +++ b/pdf.js @@ -4137,9 +4137,6 @@ var CanvasExtraState = (function() { this.charSpacing = 0; this.wordSpacing = 0; this.textHScale = 1; - // Path variables - this.pathX = 0; - this.pathY = 0; // Color spaces this.fillColorSpaceObj = null; this.strokeColorSpaceObj = null; @@ -4152,7 +4149,11 @@ var CanvasExtraState = (function() { constructor.prototype = { clone: function canvasextra_clone() { return Object.create(this); - } + }, + setCurrentPoint: function canvasextra_setCurrentPoint(x, y) { + this.x = x; + this.y = y; + }, }; return constructor; })(); @@ -4279,38 +4280,24 @@ var CanvasGraphics = (function() { // Path moveTo: function(x, y) { this.ctx.moveTo(x, y); - - var current = this.current; - current.pathX = x; - current.pathY = y; + this.current.setCurrentPoint(x, y); }, lineTo: function(x, y) { this.ctx.lineTo(x, y); - - var current = this.current; - current.pathX = x; - current.pathY = y; + this.current.setCurrentPoint(x, y); }, curveTo: function(x1, y1, x2, y2, x3, y3) { this.ctx.bezierCurveTo(x1, y1, x2, y2, x3, y3); - - var current = this.current; - current.pathX = x3; - current.pathY = y3; + this.current.setCurrentPoint(x3, y3); }, curveTo2: function(x2, y2, x3, y3) { var current = this.current; - this.ctx.bezierCurveTo(current.pathX, current.pathY, x2, y2, x3, y3); - - current.pathX = x3; - current.pathY = y3; + this.ctx.bezierCurveTo(current.x, current.y, x2, y2, x3, y3); + current.setCurrentPoint(x3, y3); }, curveTo3: function(x1, y1, x3, y3) { this.curveTo(x1, y1, x3, y3, x3, y3); - - var current = this.current; - current.pathX = x3; - current.pathY = y3; + this.current.setCurrentPoint(x3, y3); }, closePath: function() { this.ctx.closePath();