Skip to content

Commit e2ce150

Browse files
committed
Added support for zoom factor in links
Moved stray method into plugin scope Use page object reference instead of pageNumber for destination. (wider compatibility)
1 parent 981d249 commit e2ce150

File tree

2 files changed

+90
-12
lines changed

2 files changed

+90
-12
lines changed

jspdf.plugin.annotations.js

Lines changed: 66 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@
1313
* This plugin current supports <br />
1414
* <li> Goto Page (set pageNumber in options)
1515
* <li> Goto URL (set url in options)
16-
*
16+
* <p>
17+
* The destination magnification factor can also be specified when goto is a page number or a named destination. (see documentation below)
18+
* (set magFactor in options). XYZ is the default.
19+
* </p>
1720
* <p>
1821
* Options In PDF spec Not Implemented Yet
1922
* <li> link border
@@ -25,13 +28,22 @@
2528
* </p>
2629
*/
2730

28-
function notEmpty(obj) {
29-
if (typeof obj != 'undefined') {
30-
if (obj != '') {
31-
return true;
32-
}
33-
}
34-
}
31+
/*
32+
Destination Magnification Factors
33+
See PDF 1.3 Page 386 for meanings and options
34+
35+
[supported]
36+
XYZ (options; left top zoom)
37+
Fit (no options)
38+
FitH (options: top)
39+
FitV (options: left)
40+
41+
[not supported]
42+
FitR
43+
FitB
44+
FitBH
45+
FitBV
46+
*/
3547

3648
(function(jsPDFAPI) {
3749
'use strict';
@@ -45,6 +57,14 @@ function notEmpty(obj) {
4557

4658
f2 : function(number) {
4759
return number.toFixed(2);
60+
},
61+
62+
notEmpty : function(obj) {
63+
if (typeof obj != 'undefined') {
64+
if (obj != '') {
65+
return true;
66+
}
67+
}
4868
}
4969
};
5070

@@ -64,7 +84,7 @@ function notEmpty(obj) {
6484
for (var a = 0; a < pageAnnos.length; a++) {
6585
var anno = pageAnnos[a];
6686
if (anno.type === 'link') {
67-
if (notEmpty(anno.options.url) || notEmpty(anno.options.pageNumber)) {
87+
if (annotationPlugin.notEmpty(anno.options.url) || annotationPlugin.notEmpty(anno.options.pageNumber)) {
6888
found = true;
6989
break;
7090
}
@@ -78,17 +98,50 @@ function notEmpty(obj) {
7898
var f2 = this.annotationPlugin.f2;
7999
for (var a = 0; a < pageAnnos.length; a++) {
80100
var anno = pageAnnos[a];
101+
81102
var k = this.internal.scaleFactor;
82103
var pageHeight = this.internal.pageSize.height;
104+
//var pageHeight = this.internal.pageSize.height * this.internal.scaleFactor;
83105
var rect = "/Rect [" + f2(anno.x * k) + " " + f2((pageHeight - anno.y) * k) + " " + f2(anno.x + anno.w * k) + " " + f2(pageHeight - (anno.y + anno.h) * k) + "] ";
106+
107+
var line = '';
84108
if (anno.options.url) {
85-
this.internal.write('<</Type /Annot /Subtype /Link ' + rect + '/Border [0 0 0] /A <</S /URI /URI (' + anno.options.url + ') >> >>')
109+
line = '<</Type /Annot /Subtype /Link ' + rect + '/Border [0 0 0] /A <</S /URI /URI (' + anno.options.url + ') >>';
86110
} else if (anno.options.pageNumber) {
87111
// first page is 0
88-
this.internal.write('<</Type /Annot /Subtype /Link ' + rect + '/Border [0 0 0] /Dest [' + (anno.options.pageNumber - 1) + ' /XYZ 0 ' + pageHeight + ' 0] >>')
112+
var pageObjId = anno.options.pageNumber * 2 + 1;
113+
line = '<</Type /Annot /Subtype /Link ' + rect + '/Border [0 0 0] /Dest [' + pageObjId + " 0 R";
114+
anno.options.magFactor = anno.options.magFactor || "XYZ";
115+
switch (anno.options.magFactor) {
116+
case 'Fit':
117+
line += ' /Fit]';
118+
break;
119+
case 'FitH':
120+
anno.options.top = anno.options.top || f2(pageHeight * k);
121+
line += ' /FitH ' + anno.options.top + ']';
122+
break;
123+
case 'FitV':
124+
anno.options.left = anno.options.left || 0;
125+
line += ' /FitV ' + anno.options.left + ']';
126+
break;
127+
case 'XYZ':
128+
default:
129+
anno.options.top = anno.options.top || f2(pageHeight * k);
130+
anno.options.left = anno.options.left || 0;
131+
// 0 or null zoom will not change zoom factor
132+
if (typeof anno.options.zoom === 'undefined'){
133+
anno.options.zoom = 0;
134+
}
135+
line += ' /XYZ ' + anno.options.left + ' ' + anno.options.top + ' ' + anno.options.zoom + ']';
136+
break;
137+
}
89138
} else {
90139
// TODO error - should not be here
91140
}
141+
if (line != '') {
142+
line += " >>";
143+
this.internal.write(line);
144+
}
92145
}
93146
this.internal.write("]");
94147
}
@@ -112,6 +165,7 @@ function notEmpty(obj) {
112165

113166
/**
114167
* Currently only supports single line text.
168+
* Returns the width of the text/link
115169
*/
116170
jsPDFAPI.textWithLink = function(text,x,y,options) {
117171
'use strict';
@@ -122,7 +176,7 @@ function notEmpty(obj) {
122176
// Or ability to draw text on top, bottom, center, or baseline.
123177
y += height * .2;
124178
this.link(x, y - height, width, height, options);
125-
return this;
179+
return width;
126180
};
127181

128182
//TODO move into external library

test/test_annotation.html

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
// Create pages with a table of contents.
3232
// TOC links to each page
3333
// Each page links back to TOC and to an external URL
34+
// Supported magnification Options are included.
3435
var y = 20;
3536
var text = 'Table of Contents';
3637
pdf.text(text, 20, y);
@@ -40,8 +41,24 @@
4041
text = "Page " + i;
4142
pdf.textWithLink(text, 20, y, {pageNumber:i});
4243
y += pdf.getLineHeight();
44+
45+
var x = 20;
46+
var width = pdf.textWithLink(" [100%]", x, y, {pageNumber:i, magFactor:'XYZ', zoom:1});
47+
x += width;
48+
var width = pdf.textWithLink(" [200%]", x, y, {pageNumber:i, magFactor:'XYZ', zoom:2});
49+
x += width;
50+
var width = pdf.textWithLink(" [50%]", x, y, {pageNumber:i, magFactor:'XYZ', zoom:.5});
51+
x += width;
52+
var width = pdf.textWithLink(" [Fit]", x, y, {pageNumber:i, magFactor:'Fit'});
53+
x += width;
54+
var width = pdf.textWithLink(" [FitH]", x, y, {pageNumber:i, magFactor:'FitH'});
55+
x += width;
56+
var width = pdf.textWithLink(" [FitV]", x, y, {pageNumber:i, magFactor:'FitV'});
57+
58+
y += pdf.getLineHeight();
4359
}
4460

61+
// Create Test Pages
4562
for (var i=2; i<10; i++){
4663
pdf.addPage();
4764
y = 20;
@@ -99,6 +116,13 @@
99116
</head>
100117

101118
<body style='background-color: silver; margin: 0;'>
119+
<p>
120+
Chrome default PDF reader currently does not support magFactor links, although links still work after manualy changing magFactor.
121+
<br />
122+
Firefox has a bug displaying annotations after the magFactor changes, but links do work.
123+
<br />
124+
To test magFactor links [...] without bugs, use Adobe Reader or compatible application.
125+
</p>
102126
<pre id='sourcecode'></pre>
103127
<iframe id='pdfframe' style='width: 100%; height: 100%; position: absolute'></iframe>
104128
</body>

0 commit comments

Comments
 (0)