diff --git a/src/fonts.js b/src/fonts.js index 1a4366c19..f83d1e80d 100644 --- a/src/fonts.js +++ b/src/fonts.js @@ -1785,6 +1785,12 @@ var Font = (function Font() { } properties.hasShortCmap = hasShortCmap; + // remove glyph references outside range of avaialable glyphs + for (var i = 0, ii = ids.length; i < ii; i++) { + if (ids[i] >= numGlyphs) + ids[i] = 0; + } + createGlyphNameMap(glyphs, ids, properties); this.glyphNameMap = properties.glyphNameMap; @@ -2102,9 +2108,9 @@ var Font = (function Font() { break; case 'Type1': var glyphName = this.differences[charcode] || this.encoding[charcode]; + if (!isNum(width)) + width = this.widths[glyphName]; if (this.noUnicodeAdaptation) { - if (!isNum(width)) - width = this.widths[glyphName]; unicode = GlyphsUnicode[glyphName] || charcode; break; } diff --git a/test/pdfs/.gitignore b/test/pdfs/.gitignore index dd0dceced..d3caa968a 100644 --- a/test/pdfs/.gitignore +++ b/test/pdfs/.gitignore @@ -18,3 +18,4 @@ !cmykjpeg.pdf !issue840.pdf !scan-bad.pdf +!freeculture.pdf diff --git a/test/pdfs/bpl13210.pdf.link b/test/pdfs/bpl13210.pdf.link new file mode 100644 index 000000000..7cde56a22 --- /dev/null +++ b/test/pdfs/bpl13210.pdf.link @@ -0,0 +1 @@ +http://h20000.www2.hp.com/bc/docs/support/SupportManual/bpl13210/bpl13210.pdf diff --git a/test/pdfs/freeculture.pdf b/test/pdfs/freeculture.pdf new file mode 100644 index 000000000..8b27e9355 Binary files /dev/null and b/test/pdfs/freeculture.pdf differ diff --git a/test/test_manifest.json b/test/test_manifest.json index ca09d14bc..5cf266c63 100644 --- a/test/test_manifest.json +++ b/test/test_manifest.json @@ -87,6 +87,13 @@ "rounds": 1, "type": "eq" }, + { "id": "freeculture", + "file": "pdfs/freeculture.pdf", + "md5": "dcdf3a8268e6a18938a42d5149efcfca", + "rounds": 1, + "pageLimit": 5, + "type": "eq" + }, { "id": "wnv_chinese-pdf", "file": "pdfs/wnv_chinese.pdf", "md5": "db682638e68391125e8982d3c984841e", @@ -302,6 +309,14 @@ "rounds": 1, "type": "eq" }, + { "id": "bpl13210", + "file": "pdfs/bpl13210.pdf", + "md5": "8a08512baa9fa95378d9ad4b995947c7", + "link": true, + "pageLimit": 5, + "rounds": 1, + "type": "eq" + }, { "id": "tutorial", "file": "pdfs/tutorial.pdf", "md5": "6e122f618c27f3aa9a689423e3be6b8d", diff --git a/web/viewer.html b/web/viewer.html index ffd4327a7..53ca2a247 100644 --- a/web/viewer.html +++ b/web/viewer.html @@ -27,9 +27,9 @@ - - + +
@@ -139,4 +139,3 @@
- diff --git a/web/viewer.js b/web/viewer.js index 5cccd61f1..121ab6d0c 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -359,6 +359,7 @@ var PDFView = { outlineScrollView.setAttribute('hidden', 'true'); thumbsSwitchButton.setAttribute('data-selected', true); outlineSwitchButton.removeAttribute('data-selected'); + updateThumbViewArea(); break; case 'outline': thumbsScrollView.setAttribute('hidden', 'true'); @@ -393,6 +394,34 @@ var PDFView = { currentHeight += singlePage.height * singlePage.scale + kBottomMargin; } return visiblePages; + }, + + getVisibleThumbs: function pdfViewGetVisibleThumbs() { + var thumbs = this.thumbnails; + var kBottomMargin = 5; + var visibleThumbs = []; + + var view = document.getElementById('sidebarScrollView'); + var currentHeight = kBottomMargin; + var top = view.scrollTop; + for (var i = 1; i <= thumbs.length; ++i) { + var thumb = thumbs[i - 1]; + var thumbHeight = thumb.height * thumb.scaleY + kBottomMargin; + if (currentHeight + thumbHeight > top) + break; + + currentHeight += thumbHeight; + } + + var bottom = top + view.clientHeight; + for (; i <= thumbs.length && currentHeight < bottom; ++i) { + var singleThumb = thumbs[i - 1]; + visibleThumbs.push({ id: singleThumb.id, y: currentHeight, + view: singleThumb }); + currentHeight += singleThumb.height * singleThumb.scaleY + kBottomMargin; + } + + return visibleThumbs; } }; @@ -591,6 +620,19 @@ var ThumbnailView = function thumbnailView(container, page, id, pageRatio) { return false; }; + var view = page.view; + this.width = view.width; + this.height = view.height; + this.id = id; + + var maxThumbSize = 134; + var canvasWidth = pageRatio >= 1 ? maxThumbSize : + maxThumbSize * pageRatio; + var canvasHeight = pageRatio <= 1 ? maxThumbSize : + maxThumbSize / pageRatio; + var scaleX = this.scaleX = (canvasWidth / this.width); + var scaleY = this.scaleY = (canvasHeight / this.height); + var div = document.createElement('div'); div.id = 'thumbnailContainer' + id; div.className = 'thumbnail'; @@ -605,11 +647,8 @@ var ThumbnailView = function thumbnailView(container, page, id, pageRatio) { canvas.id = 'thumbnail' + id; canvas.mozOpaque = true; - var maxThumbSize = 134; - canvas.width = pageRatio >= 1 ? maxThumbSize : - maxThumbSize * pageRatio; - canvas.height = pageRatio <= 1 ? maxThumbSize : - maxThumbSize / pageRatio; + canvas.width = canvasWidth; + canvas.height = canvasHeight; div.setAttribute('data-loaded', true); div.appendChild(canvas); @@ -621,8 +660,6 @@ var ThumbnailView = function thumbnailView(container, page, id, pageRatio) { ctx.restore(); var view = page.view; - var scaleX = (canvas.width / page.width); - var scaleY = (canvas.height / page.height); ctx.translate(-view.x * scaleX, -view.y * scaleY); div.style.width = (view.width * scaleX) + 'px'; div.style.height = (view.height * scaleY) + 'px'; @@ -703,6 +740,9 @@ window.addEventListener('load', function webViewerLoad(evt) { document.getElementById('fileInput').setAttribute('hidden', 'true'); else document.getElementById('fileInput').value = null; + + var sidebarScrollView = document.getElementById('sidebarScrollView'); + sidebarScrollView.addEventListener('scroll', updateThumbViewArea, true); }, true); window.addEventListener('unload', function webViewerUnload(evt) { @@ -741,6 +781,29 @@ window.addEventListener('scroll', function webViewerScroll(evt) { updateViewarea(); }, true); + +var thumbnailTimer; + +function updateThumbViewArea() { + // Only render thumbs after pausing scrolling for this amount of time + // (makes UI more responsive) + var delay = 50; // in ms + + if (thumbnailTimer) + clearTimeout(thumbnailTimer); + + thumbnailTimer = setTimeout(function() { + var visibleThumbs = PDFView.getVisibleThumbs(); + for (var i = 0; i < visibleThumbs.length; i++) { + var thumb = visibleThumbs[i]; + PDFView.thumbnails[thumb.id - 1].draw(); + } + }, delay); +} + +window.addEventListener('transitionend', updateThumbViewArea, true); +window.addEventListener('webkitTransitionEnd', updateThumbViewArea, true); + window.addEventListener('resize', function webViewerResize(evt) { if (document.getElementById('pageWidthOption').selected || document.getElementById('pageFitOption').selected) @@ -781,25 +844,6 @@ window.addEventListener('change', function webViewerChange(evt) { document.getElementById('download').setAttribute('hidden', 'true'); }, true); -window.addEventListener('transitionend', function webViewerTransitionend(evt) { - var pageIndex = 0; - var pagesCount = PDFView.pages.length; - - var container = document.getElementById('sidebarView'); - container._interval = window.setInterval(function interval() { - // skipping the thumbnails with set images - while (pageIndex < pagesCount && PDFView.thumbnails[pageIndex].hasImage) - pageIndex++; - - if (pageIndex >= pagesCount) { - window.clearInterval(container._interval); - return; - } - - PDFView.thumbnails[pageIndex++].draw(); - }, 500); -}, true); - window.addEventListener('scalechange', function scalechange(evt) { var customScaleOption = document.getElementById('customScaleOption'); customScaleOption.selected = false;