diff --git a/crypto.js b/crypto.js index 652f53b2c..4aaca9520 100644 --- a/crypto.js +++ b/crypto.js @@ -543,7 +543,7 @@ var CipherTransformFactory = (function() { key[i++] = 0x54; } var hash = md5(key, 0, i); - return hash.subarray(0, Math.min(key.length, 16)); + return hash.subarray(0, Math.min(encryptionKey.length + 5, 16)); } function buildCipherConstructor(cf, name, num, gen, key) { diff --git a/fonts.js b/fonts.js index 3a80d151e..2d7ff94f5 100755 --- a/fonts.js +++ b/fonts.js @@ -1309,7 +1309,7 @@ var Font = (function Font() { return constructor; })(); -/** +/* * Type1Parser encapsulate the needed code for parsing a Type1 font * program. Some of its logic depends on the Type2 charstrings * structure. @@ -1534,7 +1534,7 @@ var Type1Parser = function() { return { charstring: charstring, width: width, lsb: lsb }; }; - /** + /* * Returns an object containing a Subrs array and a CharStrings * array extracted from and eexec encrypted block of data */ diff --git a/glyphlist.js b/glyphlist.js index 3551e6173..9be0e8d5a 100644 --- a/glyphlist.js +++ b/glyphlist.js @@ -1087,6 +1087,8 @@ var GlyphsUnicode = { amsquare: 0x33C2, anbopomofo: 0x3122, angbopomofo: 0x3124, + angbracketleft: 0x3008, // This glyph is missing from Adobe's original list. + angbracketright: 0x3009, // This glyph is missing from Adobe's original list. angkhankhuthai: 0x0E5A, angle: 0x2220, anglebracketleft: 0x3008, @@ -1385,6 +1387,7 @@ var GlyphsUnicode = { cieucparenkorean: 0x3208, cieucuparenkorean: 0x321C, circle: 0x25CB, + circlecopyrt: 0x00A9, // This glyph is missing from Adobe's original list. circlemultiply: 0x2297, circleot: 0x2299, circleplus: 0x2295, @@ -4287,8 +4290,3 @@ var GlyphsUnicode = { zukatakana: 0x30BA }; -// Add missing glyphs from the Adobe's original list -GlyphsUnicode.angbracketleft = 0x3008; -GlyphsUnicode.angbracketright = 0x3009; -GlyphsUnicode.circlecopyrt = 0x00A9; - diff --git a/pdf.js b/pdf.js index a3900b58b..e7095b692 100644 --- a/pdf.js +++ b/pdf.js @@ -3418,7 +3418,8 @@ var Page = (function() { } } else if (annotation.has('Dest')) { // simple destination link - link.dest = annotation.get('Dest').name; + var dest = annotation.get('Dest'); + link.dest = IsName(dest) ? dest.name : dest; } links.push(link); } @@ -3482,10 +3483,10 @@ var Catalog = (function() { if (IsName(dest)) dest = dest.name; } - + var title = xref.fetchIfRef(outlineDict.get('Title')); var outlineItem = { dest: dest, - title: convertIfUnicode(outlineDict.get('Title')), + title: convertIfUnicode(title), color: outlineDict.get('C') || [0, 0, 0], count: outlineDict.get('Count'), bold: !!(outlineDict.get('F') & 2), @@ -3545,7 +3546,7 @@ var Catalog = (function() { var obj = this.catDict.get('Names'); if (obj) nameTreeRef = xref.fetchIfRef(obj).get('Dests'); - else if(this.catDict.has('Dests')) + else if (this.catDict.has('Dests')) nameDictionaryRef = this.catDict.get('Dests'); if (nameDictionaryRef) { @@ -3923,7 +3924,7 @@ var Encodings = { 'arrowdbldown', 'lozenge', 'angleleft', 'registersans', 'copyrightsans', 'trademarksans', 'summation', 'parenlefttp', 'parenleftex', 'parenleftbt', 'bracketlefttp', 'bracketleftex', 'bracketleftbt', - 'bracelefttp', 'braceleftmid', 'braceleftbt', 'braceex', ,'angleright', + 'bracelefttp', 'braceleftmid', 'braceleftbt', 'braceex',, 'angleright', 'integral', 'integraltp', 'integralex', 'integralbt', 'parenrighttp', 'parenrightex', 'parenrightbt', 'bracketrighttp', 'bracketrightex', 'bracketrightbt', 'bracerighttp', 'bracerightmid', 'bracerightbt' @@ -4278,8 +4279,8 @@ var PartialEvaluator = (function() { } // merge in the differences - var length = baseEncoding.length > diffEncoding.length ? - baseEncoding.length : diffEncoding.length; + var length = baseEncoding.length > diffEncoding.length ? + baseEncoding.length : diffEncoding.length; for (var i = 0, ii = length; i < ii; ++i) { var diffGlyph = diffEncoding[i]; var baseGlyph = baseEncoding[i]; @@ -4310,7 +4311,7 @@ var PartialEvaluator = (function() { var cmap = cmapObj.getBytes(cmapObj.length); for (var i = 0; i < cmap.length; i++) { var byte = cmap[i]; - if (byte == 0x20 || byte == 0x0A || byte == 0x3C || + if (byte == 0x20 || byte == 0x0A || byte == 0x3C || byte == 0x3E) { switch (token) { case 'useCMap': @@ -5119,15 +5120,18 @@ var CanvasGraphics = (function() { var tmpCanvas = new this.ScratchCanvas(w, h); var tmpCtx = tmpCanvas.getContext('2d'); + if (imageObj.imageMask) { + var fillColor = this.current.fillColor; + tmpCtx.fillStyle = (fillColor && fillColor.type === 'Pattern') ? + fillColor.getPattern(tmpCtx) : fillColor; + tmpCtx.fillRect(0, 0, w, h); + } var imgData = tmpCtx.getImageData(0, 0, w, h); var pixels = imgData.data; if (imageObj.imageMask) { - var inverseDecode = imageObj.decode && imageObj.decode[0] > 0; - // TODO fillColor pattern support - var fillColor = this.current.fillColor; - imageObj.fillUsingStencilMask(pixels, fillColor, - inverseDecode); + var inverseDecode = !!imageObj.decode && imageObj.decode[0] > 0; + imageObj.applyStencilMask(pixels, inverseDecode); } else imageObj.fillRgbaBuffer(pixels); @@ -6007,26 +6011,26 @@ var PDFImage = (function() { } return buf; }, - fillUsingStencilMask: function fillUsingStencilMask(buffer, - cssRgb, inverseDecode) { - var m = /rgb\((\d+),(\d+),(\d+)\)/.exec(cssRgb); // parse CSS color - var r = m[1] | 0, g = m[2] | 0, b = m[3] | 0; - var bufferLength = this.width * this.height; - var imgArray = this.image.getBytes((bufferLength + 7) >> 3); - var i, mask; - var bufferPos = 0, imgArrayPos = 0; - for (i = 0; i < bufferLength; i++) { - var buf = imgArray[imgArrayPos++]; - for (mask = 128; mask > 0; mask >>= 1) { - if (!(buf & mask) != inverseDecode) { - buffer[bufferPos++] = r; - buffer[bufferPos++] = g; - buffer[bufferPos++] = b; - buffer[bufferPos++] = 255; - } else { - buffer[bufferPos + 3] = 0; - bufferPos += 4; + applyStencilMask: function applyStencilMask(buffer, inverseDecode) { + var width = this.width, height = this.height; + var bitStrideLength = (width + 7) >> 3; + var imgArray = this.image.getBytes(bitStrideLength * height); + var imgArrayPos = 0; + var i, j, mask, buf; + // removing making non-masked pixels transparent + var bufferPos = 3; // alpha component offset + for (i = 0; i < height; i++) { + mask = 0; + for (j = 0; j < width; j++) { + if (!mask) { + buf = imgArray[imgArrayPos++]; + mask = 128; } + if (!(buf & mask) == inverseDecode) { + buffer[bufferPos] = 0; + } + bufferPos += 4; + mask >>= 1; } } }, diff --git a/test/driver.js b/test/driver.js index 9fa1cfa8c..cfa9dff75 100644 --- a/test/driver.js +++ b/test/driver.js @@ -221,7 +221,10 @@ function checkScrolling() { } function log(str) { - stdout.insertAdjacentHTML('BeforeEnd', str); + if (stdout.insertAdjacentHTML) + stdout.insertAdjacentHTML('BeforeEnd', str); + else + stdout.innerHTML += str; if (str.lastIndexOf('\n') >= 0) checkScrolling(); diff --git a/test/test.py b/test/test.py index c76df3fd4..4801c4b38 100644 --- a/test/test.py +++ b/test/test.py @@ -58,6 +58,7 @@ MIMEs = { '.html': 'text/html', '.js': 'application/javascript', '.json': 'application/json', + '.svg': 'image/svg+xml', '.pdf': 'application/pdf', '.xhtml': 'application/xhtml+xml', '.ico': 'image/x-icon', diff --git a/utils/fonts_utils.js b/utils/fonts_utils.js index edfc22186..7665906a1 100644 --- a/utils/fonts_utils.js +++ b/utils/fonts_utils.js @@ -3,7 +3,7 @@ 'use strict'; -/** +/* * The Type2 reader code below is only used for debugging purpose since Type2 * is only a CharString format and is never used directly as a Font file. * @@ -12,7 +12,7 @@ * CharString or to understand the structure of the CFF format. */ -/** +/* * Build a charset by assigning the glyph name and the human readable form * of the glyph data. */ @@ -38,7 +38,7 @@ function readCharset(aStream, aCharstrings) { return charset; } -/** +/* * Take a Type2 binary charstring as input and transform it to a human * readable representation as specified by the 'The Type 2 Charstring Format', * chapter 3.1. @@ -86,7 +86,7 @@ function readCharstringEncoding(aString) { } -/** +/* * Take a binary DICT Data as input and transform it into a human readable * form as specified by 'The Compact Font Format Specification', chapter 5. */ @@ -159,8 +159,7 @@ function readFontDictData(aString, aMap) { return fontDictDataTokens; } - -/** +/* * Take a stream as input and return an array of objects. * In CFF an INDEX is a structure with the following format: * { @@ -371,8 +370,7 @@ var Type2Parser = function(aFilePath) { * */ - -/** +/* * Write to a file to the disk (works only on Firefox in privilege mode) * but this is useful for dumping a font file to the disk and check with * fontforge or the ots program what's wrong with the file. diff --git a/web/viewer.css b/web/viewer.css index e18d9681e..18da0b3d1 100644 --- a/web/viewer.css +++ b/web/viewer.css @@ -20,6 +20,7 @@ body { top: 0px; height: 40px; width: 100%; + z-index: 1; } .separator { @@ -67,6 +68,7 @@ span#info { transition: left 0.25s ease-in-out 1s; -moz-transition: left 0.25s ease-in-out 1s; -webkit-transition: left 0.25s ease-in-out 1s; + z-index: 1; } #sidebar:hover { @@ -180,6 +182,20 @@ canvas { width: 816px; height: 1056px; margin: 10px auto; + position:relative; +} + +.page > a { + display: block; + position: absolute; +} + +.page > a:hover { + opacity: 0.2; + background: #ff0; + box-shadow: 0px 2px 10px #ff0; + -moz-box-shadow: 0px 2px 10px #ff0; + -webkit-box-shadow: 0px 2px 10px #ff0; } #viewer { diff --git a/web/viewer.js b/web/viewer.js index abeaff276..8af6e01d1 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -27,15 +27,15 @@ var PDFView = { var cssUnits = 96.0 / 72.0; for (var i = 0; i < pages.length; i++) pages[i].update(val / 100 * cssUnits); - - if(document.location.hash == '#' + this.page) - this.pages[this.page-1].draw(); + + if (document.location.hash == '#' + this.page) + this.pages[this.page - 1].draw(); else // Jump the scroll position to the correct page. document.location.hash = this.page; - var event = document.createEvent("UIEvents"); - event.initUIEvent("scalechange", false, false, window, val); + var event = document.createEvent('UIEvents'); + event.initUIEvent('scalechange', false, false, window, val); window.dispatchEvent(event); }, @@ -142,7 +142,7 @@ var PDFView = { var outlineScrollView = document.getElementById('outlineScrollView'); var thumbsSwitchButton = document.getElementById('thumbsSwitch'); var outlineSwitchButton = document.getElementById('outlineSwitch'); - switch(view) { + switch (view) { case 'thumbs': thumbsScrollView.style.display = 'block'; outlineScrollView.style.display = 'none'; @@ -212,39 +212,24 @@ var PageView = function(container, content, id, width, height, }; function setupLinks(canvas, content, scale) { + function bindLink(link, dest) { + if (dest) { + link.onclick = function() { + PDFView.navigateTo(dest); + return false; + }; + } + } var links = content.getLinks(); - var currentLink = null; - if (links.length > 0) { - canvas.addEventListener('mousemove', function(e) { - var x = e.pageX; - var y = e.pageY; - for (var p = canvas; p; p = p.offsetParent) { - x -= p.offsetLeft; - y -= p.offsetTop; - } - x /= scale; - y /= scale; - var i, n = links.length; - for (i = 0; i < n; i++) { - var link = links[i]; - if (link.x <= x && link.y <= y && - x < link.x + link.width && y < link.y + link.height) { - currentLink = link; - canvas.style.cursor = 'pointer'; - return; - } - } - currentLink = null; - canvas.style.cursor = 'default'; - }, false); - canvas.addEventListener('mousedown', function(e) { - if (!currentLink) - return; - if (currentLink.url) - window.location.href = currentLink.url; - if (currentLink.dest) - navigateTo(currentLink.dest); - }, false); + for (var i = 0; i < links.length; i++) { + var link = document.createElement('a'); + link.style.left = Math.floor(links[i].x * scale) + 'px'; + link.style.top = Math.floor(links[i].y * scale) + 'px'; + link.style.width = Math.ceil(links[i].width * scale) + 'px'; + link.style.height = Math.ceil(links[i].height * scale) + 'px'; + link.href = links[i].url || ''; + bindLink(link, links[i].dest); + div.appendChild(link); } } @@ -436,7 +421,7 @@ window.addEventListener('transitionend', function(evt) { }, true); -window.addEventListener("scalechange", function(evt) { +window.addEventListener('scalechange', function(evt) { var options = document.getElementById('scaleSelect').options; for (var i = 0; i < options.length; i++) { var option = options[i]; @@ -444,10 +429,10 @@ window.addEventListener("scalechange", function(evt) { } }, true); -window.addEventListener("pagechange", function(evt) { +window.addEventListener('pagechange', function(evt) { var page = evt.detail; document.location.hash = page; - document.getElementById("pageNumber").value = page; - document.getElementById("previous").disabled = (page == 1); - document.getElementById("next").disabled = (page == PDFView.pages.length); + document.getElementById('pageNumber').value = page; + document.getElementById('previous').disabled = (page == 1); + document.getElementById('next').disabled = (page == PDFView.pages.length); }, true);