From 5c7ecbfa28d0dad59441d3774c175ab142a3b04b Mon Sep 17 00:00:00 2001 From: notmasteryet Date: Wed, 17 Aug 2011 20:21:54 -0500 Subject: [PATCH 1/3] Basic annotation link support --- pdf.js | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++ web/viewer.js | 34 +++++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+) diff --git a/pdf.js b/pdf.js index 79ae776f6..46eb202ff 100644 --- a/pdf.js +++ b/pdf.js @@ -3154,6 +3154,9 @@ var Page = (function() { return shadow(this, 'mediaBox', ((IsArray(obj) && obj.length == 4) ? obj : null)); }, + get annotations() { + return shadow(this, 'annotations', this.inheritPageProp('Annots')); + }, get width() { var mediaBox = this.mediaBox; var rotate = this.rotate; @@ -3266,6 +3269,56 @@ var Page = (function() { rotate: this.rotate }); gfx.execute(this.code, xref, resources); gfx.endDrawing(); + }, + rotatePoint: function (x, y) { + var rotate = this.rotate; + switch (rotate) { + default: + case 0: + return {x: x, y: this.height - y}; + case 180: + return {x: this.width - x, y: y}; + case 90: + return {x: this.width - y, y: this.height - x}; + case 270: + return {x: y, y: x}; + } + }, + getLinks: function(scale) { + var xref = this.xref; + var annotations = xref.fetchIfRef(this.annotations); + var i, n = annotations.length; + var links = []; + for (i = 0; i < n; ++i) { + var annotation = xref.fetch(annotations[i]); + if (!IsDict(annotation, 'Annot')) + continue; + var subtype = annotation.get("Subtype"); + if (!IsName(subtype) || subtype.name != 'Link') + continue; + var rect = annotation.get("Rect"); + var topLeftCorner = this.rotatePoint(rect[0], rect[1]); + var bottomRightCorner = this.rotatePoint(rect[2], rect[3]); + + var link = {}; + link.x = scale * Math.min(topLeftCorner.x, bottomRightCorner.x); + link.y = scale * Math.min(topLeftCorner.y, bottomRightCorner.y); + link.width = scale * Math.abs(topLeftCorner.x - bottomRightCorner.x); + link.height = scale * Math.abs(topLeftCorner.y - bottomRightCorner.y); + var a = annotation.get("A"); + if (a) { + switch(a.get("S").name) { + case "URI": + link.url = a.get("URI"); + break; + default: + TODO("other link types"); + break; + } + } + links.push(link); + } + return links; } }; diff --git a/web/viewer.js b/web/viewer.js index 0307e7ea3..e4db38bc8 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -165,6 +165,38 @@ var PageView = function(container, content, id, width, height, stats) { div.removeChild(div.lastChild); }; + function setupLinks(canvas, content, scale) { + var links = content.getLinks(scale); + 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; + } + for (var i = 0; i < links.length; i++) { + var link = links[i]; + if (!link.url) + continue; + 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) { + window.location.href = currentLink.url; + }, false); + } + } + this.draw = function() { if (div.hasChildNodes()) { this.updateStats(); @@ -188,6 +220,8 @@ var PageView = function(container, content, id, width, height, stats) { stats.begin = Date.now(); this.content.startRendering(ctx, this.updateStats); + setupLinks(canvas, this.content, this.scale); + return true; }; From c2eaa55cd97ee64451dea80472c4d16b1aa1a390 Mon Sep 17 00:00:00 2001 From: notmasteryet Date: Thu, 18 Aug 2011 22:48:07 -0500 Subject: [PATCH 2/3] Move scale out of pdf.js --- pdf.js | 10 +++++----- web/viewer.js | 4 +++- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/pdf.js b/pdf.js index 79a9bba77..63aefcd32 100644 --- a/pdf.js +++ b/pdf.js @@ -3340,7 +3340,7 @@ var Page = (function() { return {x: y, y: x}; } }, - getLinks: function(scale) { + getLinks: function() { var xref = this.xref; var annotations = xref.fetchIfRef(this.annotations); var i, n = annotations.length; @@ -3357,10 +3357,10 @@ var Page = (function() { var bottomRightCorner = this.rotatePoint(rect[2], rect[3]); var link = {}; - link.x = scale * Math.min(topLeftCorner.x, bottomRightCorner.x); - link.y = scale * Math.min(topLeftCorner.y, bottomRightCorner.y); - link.width = scale * Math.abs(topLeftCorner.x - bottomRightCorner.x); - link.height = scale * Math.abs(topLeftCorner.y - bottomRightCorner.y); + link.x = Math.min(topLeftCorner.x, bottomRightCorner.x); + link.y = Math.min(topLeftCorner.y, bottomRightCorner.y); + link.width = Math.abs(topLeftCorner.x - bottomRightCorner.x); + link.height = Math.abs(topLeftCorner.y - bottomRightCorner.y); var a = annotation.get("A"); if (a) { switch(a.get("S").name) { diff --git a/web/viewer.js b/web/viewer.js index e4db38bc8..b1e28407f 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -166,7 +166,7 @@ var PageView = function(container, content, id, width, height, stats) { }; function setupLinks(canvas, content, scale) { - var links = content.getLinks(scale); + var links = content.getLinks(); var currentLink = null; if (links.length > 0) { @@ -177,6 +177,8 @@ var PageView = function(container, content, id, width, height, stats) { x -= p.offsetLeft; y -= p.offsetTop; } + x /= scale; + y /= scale; for (var i = 0; i < links.length; i++) { var link = links[i]; if (!link.url) From 1e8090c19d1f885cf7ff93ce5c6bad71f08972ff Mon Sep 17 00:00:00 2001 From: notmasteryet Date: Thu, 18 Aug 2011 23:12:10 -0500 Subject: [PATCH 3/3] brace fix --- web/viewer.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/web/viewer.js b/web/viewer.js index b1e28407f..e501a10b2 100644 --- a/web/viewer.js +++ b/web/viewer.js @@ -168,8 +168,7 @@ var PageView = function(container, content, id, width, height, stats) { function setupLinks(canvas, content, scale) { var links = content.getLinks(); var currentLink = null; - if (links.length > 0) - { + if (links.length > 0) { canvas.addEventListener('mousemove', function(e) { var x = e.pageX; var y = e.pageY;