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;
};