diff --git a/fonts.js b/fonts.js index c40b9f192..2172d12b2 100755 --- a/fonts.js +++ b/fonts.js @@ -220,7 +220,7 @@ var FontLoader = { } src += ' var fontNames=[' + fontNamesArray + '];\n'; src += ' window.onload = function () {\n'; - src += ' top.postMessage(JSON.stringify(fontNames), "*");\n'; + src += ' parent.postMessage(JSON.stringify(fontNames), "*");\n'; src += ' }'; src += ''; for (var i = 0; i < names.length; ++i) { @@ -1868,7 +1868,8 @@ CFF.prototype = { return null; }, - getOrderedCharStrings: function cff_getOrderedCharStrings(glyphs, properties) { + getOrderedCharStrings: function cff_getOrderedCharStrings(glyphs, + properties) { var charstrings = []; var missings = []; diff --git a/pdf.js b/pdf.js index 32e13817f..597e8b23f 100644 --- a/pdf.js +++ b/pdf.js @@ -4381,7 +4381,7 @@ var PartialEvaluator = (function() { var descriptor = xref.fetch(fd); var fontName = fontDict.get('Name'); if (!fontName) - fontName = xref.fetchIfRef(descriptor.get('FontName'));; + fontName = xref.fetchIfRef(descriptor.get('FontName')); assertWellFormed(IsName(fontName), 'invalid font name'); fontName = fontName.name.replace(/[\+,\-]/g, '_'); @@ -5106,7 +5106,7 @@ var CanvasGraphics = (function() { var inverseDecode = !!imageObj.decode && imageObj.decode[0] > 0; imageObj.applyStencilMask(pixels, inverseDecode); } else - imageObj.fillRgbaBuffer(pixels); + imageObj.fillRgbaBuffer(pixels, imageObj.decode); tmpCtx.putImageData(imgData, 0, 0); ctx.drawImage(tmpCanvas, 0, -h); @@ -5901,7 +5901,7 @@ var PDFImage = (function() { }; constructor.prototype = { - getComponents: function getComponents(buffer) { + getComponents: function getComponents(buffer, decodeMap) { var bpc = this.bpc; if (bpc == 8) return buffer; @@ -5915,6 +5915,11 @@ var PDFImage = (function() { var output = new Uint8Array(length); if (bpc == 1) { + var valueZero = 0, valueOne = 255; + if (decodeMap) { + valueZero = decodeMap[0] ? 255 : 0; + valueOne = decodeMap[1] ? 255 : 0; + } var rowComps = width * numComps; var mask = 0; var buf = 0; @@ -5932,13 +5937,11 @@ var PDFImage = (function() { mask = 128; } - var t = buf & mask; - if (t == 0) - output[i] = 0; - else - output[i] = 255; + output[i] = !(buf & mask) ? valueZero : valueOne; } } else { + if (decodeMap != null) + TODO('interpolate component values'); var rowComps = width * numComps; var bits = 0; var buf = 0; @@ -6007,7 +6010,7 @@ var PDFImage = (function() { } } }, - fillRgbaBuffer: function fillRgbaBuffer(buffer) { + fillRgbaBuffer: function fillRgbaBuffer(buffer, decodeMap) { var numComps = this.numComps; var width = this.width; var height = this.height; @@ -6017,7 +6020,8 @@ var PDFImage = (function() { var rowBytes = (width * numComps * bpc + 7) >> 3; var imgArray = this.image.getBytes(height * rowBytes); - var comps = this.colorSpace.getRgbBuffer(this.getComponents(imgArray)); + var comps = this.colorSpace.getRgbBuffer( + this.getComponents(imgArray, decodeMap)); var compsPos = 0; var opacity = this.getOpacity(); var opacityPos = 0; diff --git a/test/pdfs/cable.pdf.link b/test/pdfs/cable.pdf.link new file mode 100644 index 000000000..9cf92a5b8 --- /dev/null +++ b/test/pdfs/cable.pdf.link @@ -0,0 +1 @@ +http://www.wrapon.com/docs/PIPEHEATCABLE.PDF diff --git a/test/test.py b/test/test.py index 4801c4b38..d1e798d86 100644 --- a/test/test.py +++ b/test/test.py @@ -103,18 +103,49 @@ class PDFTestHandler(BaseHTTPRequestHandler): with open(path, "rb") as f: self.wfile.write(f.read()) + def sendIndex(self, path, query): + if not path.endswith("/"): + # we need trailing slash + self.send_response(301) + redirectLocation = path + "/" + if query: + redirectLocation += "?" + query + self.send_header("Location", redirectLocation) + self.end_headers() + return + + self.send_response(200) + self.send_header("Content-Type", "text/html") + self.end_headers() + if query == "frame": + self.wfile.write("" + + "") + return + + location = os.path.abspath(os.path.realpath(DOC_ROOT + os.sep + path)) + self.wfile.write("

PDFs of " + path + "

\n") + for filename in os.listdir(location): + if filename.lower().endswith('.pdf'): + self.wfile.write("" + + filename + "
\n") + self.wfile.write("") + def do_GET(self): url = urlparse(self.path) # Ignore query string path, _ = url.path, url.query path = os.path.abspath(os.path.realpath(DOC_ROOT + os.sep + path)) prefix = os.path.commonprefix(( path, DOC_ROOT )) - _, ext = os.path.splitext(path) + _, ext = os.path.splitext(path.lower()) if url.path == "/favicon.ico": self.sendFile(os.path.join(DOC_ROOT, "test", "resources", "favicon.ico"), ext) return + if os.path.isdir(path): + self.sendIndex(url.path, url.query) + return + if not (prefix == DOC_ROOT and os.path.isfile(path) and ext in MIMEs): diff --git a/test/test_manifest.json b/test/test_manifest.json index 90a9f8a77..a83ca2fb1 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -97,5 +97,11 @@ "link": true, "rounds": 1, "type": "load" + }, + { "id": "cable", + "file": "pdfs/cable.pdf", + "link": true, + "rounds": 1, + "type": "eq" } ] diff --git a/web/compatibility.js b/web/compatibility.js old mode 100644 new mode 100755 index d286692b1..e9a769163 --- a/web/compatibility.js +++ b/web/compatibility.js @@ -148,10 +148,39 @@ Function.prototype.bind = function(obj) { var fn = this, headArgs = Array.prototype.slice.call(arguments, 1); - var binded = function(tailArgs) { - var args = headArgs.concat(tailArgs); + var bound = function() { + var args = Array.prototype.concat.apply(headArgs, arguments); return fn.apply(obj, args); }; - return binded; + return bound; }; })(); + +// IE9 text/html data URI +(function() { + if (document.documentMode !== 9) + return; + // overriding the src property + var originalSrcDescriptor = Object.getOwnPropertyDescriptor( + HTMLIFrameElement.prototype, 'src'); + Object.defineProperty(HTMLIFrameElement.prototype, 'src', { + get: function() { return this.$src; }, + set: function(src) { + this.$src = src; + if (src.substr(0, 14) != 'data:text/html') { + originalSrcDescriptor.set.call(this, src); + return; + } + // for text/html, using blank document and then + // document's open, write, and close operations + originalSrcDescriptor.set.call(this, 'about:blank'); + setTimeout((function() { + var doc = this.contentDocument; + doc.open('text/html'); + doc.write(src.substr(src.indexOf(',') + 1)); + doc.close(); + }).bind(this), 0); + }, + enumerable: true + }); +})(); diff --git a/web/viewer.css b/web/viewer.css old mode 100644 new mode 100755 index 18da0b3d1..a8578eb7e --- a/web/viewer.css +++ b/web/viewer.css @@ -36,6 +36,11 @@ body { line-height: 32px; } +#controls > button > img { + width: 32px; + height: 32px; +} + #controls > button[disabled] > img { opacity: 0.5; } @@ -159,6 +164,11 @@ span#info { -webkit-box-shadow: 0px 4px 10px #000; } +#sidebarControls > button > img { + width: 32px; + height: 32px; +} + #sidebarControls > button[disabled] > img { opacity: 0.5; } @@ -210,3 +220,34 @@ canvas { -webkit-box-shadow: 0px 2px 10px #ff0; } +/* === Printed media overrides === */ +@media print { + #sidebar { + display: none; + } + + #controls { + display: none; + } + + #viewer { + margin: 0; + padding: 0; + } + + .page { + display: none; + margin: 0; + } + + .page canvas { + box-shadow: none; + -moz-box-shadow: none; + -webkit-box-shadow: none; + } + + .page[data-loaded] { + display: block; + page-break-after: always; + } +} diff --git a/web/viewer.js b/web/viewer.js index 8af6e01d1..243afb7e5 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -87,6 +87,8 @@ var PDFView = { navigateTo: function(dest) { if (typeof dest === 'string') dest = this.destinations[dest]; + if (!(dest instanceof Array)) + return; // invalid destination // dest array looks like that: var destRef = dest[0]; var pageNumber = this.pagesRefMap[destRef.num + ' ' + destRef.gen + ' R']; @@ -209,6 +211,7 @@ var PageView = function(container, content, id, width, height, while (div.hasChildNodes()) div.removeChild(div.lastChild); + div.removeAttribute('data-loaded'); }; function setupLinks(canvas, content, scale) { @@ -257,6 +260,7 @@ var PageView = function(container, content, id, width, height, this.content.startRendering(ctx, this.updateStats); setupLinks(canvas, this.content, this.scale); + div.setAttribute('data-loaded', true); return true; };