| 9 |
lars |
1 |
$(document).ready(function(){
|
|
|
2 |
|
|
|
3 |
var dump = false // turn to true to dump contents of PDFs into textareas instead.
|
|
|
4 |
|
|
|
5 |
if (typeof atob === 'undefined') {
|
|
|
6 |
atob = function (data) {
|
|
|
7 |
// Decodes string using MIME base64 algorithm
|
|
|
8 |
//
|
|
|
9 |
// version: 1109.2015
|
|
|
10 |
// discuss at: http://phpjs.org/functions/base64_decode
|
|
|
11 |
// + original by: Tyler Akins (http://rumkin.com)
|
|
|
12 |
// + improved by: Thunder.m
|
|
|
13 |
// + input by: Aman Gupta
|
|
|
14 |
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
|
|
|
15 |
// + bugfixed by: Onno Marsman
|
|
|
16 |
// + bugfixed by: Pellentesque Malesuada
|
|
|
17 |
// + improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
|
|
|
18 |
// + input by: Brett Zamir (http://brett-zamir.me)
|
|
|
19 |
// + bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
|
|
|
20 |
// - depends on: utf8_decode
|
|
|
21 |
// * example 1: base64_decode('S2V2aW4gdmFuIFpvbm5ldmVsZA==');
|
|
|
22 |
// * returns 1: 'Kevin van Zonneveld'
|
|
|
23 |
|
|
|
24 |
var b64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
|
|
|
25 |
var o1, o2, o3, h1, h2, h3, h4, bits,
|
|
|
26 |
ac = 0,
|
|
|
27 |
i = 0,
|
|
|
28 |
l = data.length
|
|
|
29 |
tmp_arr = [];
|
|
|
30 |
|
|
|
31 |
do { // unpack four hexets into three octets using index points in b64
|
|
|
32 |
h1 = b64.indexOf(data.charAt(i++));
|
|
|
33 |
h2 = b64.indexOf(data.charAt(i++));
|
|
|
34 |
h3 = b64.indexOf(data.charAt(i++));
|
|
|
35 |
h4 = b64.indexOf(data.charAt(i++));
|
|
|
36 |
|
|
|
37 |
bits = h1 << 18 | h2 << 12 | h3 << 6 | h4;
|
|
|
38 |
|
|
|
39 |
o1 = bits >> 16 & 0xff;
|
|
|
40 |
o2 = bits >> 8 & 0xff;
|
|
|
41 |
o3 = bits & 0xff;
|
|
|
42 |
|
|
|
43 |
if (h3 == 64) {
|
|
|
44 |
tmp_arr[ac++] = String.fromCharCode(o1);
|
|
|
45 |
} else if (h4 == 64) {
|
|
|
46 |
tmp_arr[ac++] = String.fromCharCode(o1, o2);
|
|
|
47 |
} else {
|
|
|
48 |
tmp_arr[ac++] = String.fromCharCode(o1, o2, o3);
|
|
|
49 |
}
|
|
|
50 |
} while (i < l);
|
|
|
51 |
|
|
|
52 |
return tmp_arr.join('');
|
|
|
53 |
}
|
|
|
54 |
}
|
|
|
55 |
|
|
|
56 |
var displayInTextArea = function(output, label) {
|
|
|
57 |
var $l = $('<label for="'+label+'">'+label+'</label>').appendTo(document.body)
|
|
|
58 |
$('<textarea id="'+label+'"></textarea>').appendTo($l).text(btoa(output))
|
|
|
59 |
}
|
|
|
60 |
|
|
|
61 |
var datestringregex = /\/CreationDate \(D:\d+\)/
|
|
|
62 |
, replacementdatestring = '/CreationDate (D:0)'
|
|
|
63 |
, producerstringregex = /\/Producer\s+\(jsPDF\s+\d+\)/
|
|
|
64 |
, replacementproducerstring = '/Producer (jsPDF 0)'
|
|
|
65 |
, removeMinorDiffs = function(t){
|
|
|
66 |
t = t.replace(datestringregex, replacementdatestring)
|
|
|
67 |
t = t.replace(producerstringregex, replacementproducerstring)
|
|
|
68 |
if (t.trim)
|
|
|
69 |
return t.trim()
|
|
|
70 |
else
|
|
|
71 |
return t
|
|
|
72 |
}
|
|
|
73 |
, testinventory = {
|
|
|
74 |
"001_blankpdf.pdf": function(){
|
|
|
75 |
var doc = new jsPDF()
|
|
|
76 |
return doc.output()
|
|
|
77 |
}
|
|
|
78 |
, "002_twopagedoc.pdf":function(){
|
|
|
79 |
var doc = new jsPDF()
|
|
|
80 |
doc.text('Hello world!', 20, 20)
|
|
|
81 |
doc.text('This is client-side Javascript, pumping out a PDF.', 20, 30)
|
|
|
82 |
doc.addPage()
|
|
|
83 |
doc.text('Do you like that?', 20, 20)
|
|
|
84 |
return doc.output()
|
|
|
85 |
}
|
|
|
86 |
, "002_twopagedoc_oldapi.pdf":function(){
|
|
|
87 |
var doc = new jsPDF()
|
|
|
88 |
doc.text(20, 20, 'Hello world!')
|
|
|
89 |
doc.text(20, 30, 'This is client-side Javascript, pumping out a PDF.')
|
|
|
90 |
doc.addPage()
|
|
|
91 |
doc.text(20, 20, 'Do you like that?')
|
|
|
92 |
return doc.output()
|
|
|
93 |
}
|
|
|
94 |
, "003_demolandscape.pdf":function(){
|
|
|
95 |
var doc = new jsPDF('landscape')
|
|
|
96 |
doc.text('Hello landscape world!', 20, 20)
|
|
|
97 |
return doc.output()
|
|
|
98 |
}
|
|
|
99 |
, "004_fontsizes.pdf":function(){
|
|
|
100 |
var doc = new jsPDF()
|
|
|
101 |
doc.setFontSize(22)
|
|
|
102 |
doc.text(20, 20, 'This is a title')
|
|
|
103 |
|
|
|
104 |
doc.setFontSize(16)
|
|
|
105 |
doc.text(20, 30, 'This is some normal sized text underneath.');
|
|
|
106 |
|
|
|
107 |
return doc.output()
|
|
|
108 |
}
|
|
|
109 |
, "005_demofonttypes.pdf":function(){
|
|
|
110 |
var doc = new jsPDF()
|
|
|
111 |
|
|
|
112 |
doc.text(20, 20, 'This is the default font.')
|
|
|
113 |
|
|
|
114 |
doc.setFont("courier")
|
|
|
115 |
doc.setFontType("normal")
|
|
|
116 |
doc.text(20, 30, 'This is courier normal.')
|
|
|
117 |
|
|
|
118 |
doc.setFont("times")
|
|
|
119 |
doc.setFontType("italic")
|
|
|
120 |
doc.text(20, 40, 'This is times italic.')
|
|
|
121 |
|
|
|
122 |
doc.setFont("helvetica")
|
|
|
123 |
doc.setFontType("bold")
|
|
|
124 |
doc.text(20, 50, 'This is helvetica bold.')
|
|
|
125 |
|
|
|
126 |
doc.setFont("courier")
|
|
|
127 |
doc.setFontType("bolditalic")
|
|
|
128 |
doc.text(20, 60, 'This is courier bolditalic.')
|
|
|
129 |
|
|
|
130 |
return doc.output()
|
|
|
131 |
}
|
|
|
132 |
, "006_demotestcolors.pdf":function(){
|
|
|
133 |
var doc = new jsPDF()
|
|
|
134 |
|
|
|
135 |
doc.setTextColor(100)
|
|
|
136 |
doc.text(20, 20, 'This is gray.')
|
|
|
137 |
|
|
|
138 |
doc.setTextColor(150)
|
|
|
139 |
doc.text(20, 30, 'This is light gray.')
|
|
|
140 |
|
|
|
141 |
doc.setTextColor(255,0,0)
|
|
|
142 |
doc.text(20, 40, 'This is red.')
|
|
|
143 |
|
|
|
144 |
doc.setTextColor(0,255,0)
|
|
|
145 |
doc.text(20, 50, 'This is green.')
|
|
|
146 |
|
|
|
147 |
doc.setTextColor(0,0,255)
|
|
|
148 |
doc.text(20, 60, 'This is blue.')
|
|
|
149 |
|
|
|
150 |
return doc.output()
|
|
|
151 |
}
|
|
|
152 |
, "007_demometadata.pdf":function(){
|
|
|
153 |
var doc = new jsPDF()
|
|
|
154 |
doc.text(20, 20, 'This PDF has a title, subject, author, keywords and a creator.')
|
|
|
155 |
|
|
|
156 |
// Optional - set properties on the document
|
|
|
157 |
doc.setProperties({
|
|
|
158 |
title: 'Title',
|
|
|
159 |
subject: 'This is the subject',
|
|
|
160 |
author: 'James Hall',
|
|
|
161 |
keywords: 'generated, javascript, web 2.0, ajax',
|
|
|
162 |
creator: 'MEEE'
|
|
|
163 |
})
|
|
|
164 |
|
|
|
165 |
return doc.output()
|
|
|
166 |
}
|
|
|
167 |
, "008_demorectangles.pdf":function(){
|
|
|
168 |
var doc = new jsPDF()
|
|
|
169 |
|
|
|
170 |
doc.rect(20, 20, 10, 10); // empty square
|
|
|
171 |
|
|
|
172 |
doc.rect(40, 20, 10, 10, 'F') // filled square
|
|
|
173 |
|
|
|
174 |
doc.setDrawColor(255,0,0)
|
|
|
175 |
doc.rect(60, 20, 10, 10); // empty red square
|
|
|
176 |
|
|
|
177 |
doc.setDrawColor(255,0,0)
|
|
|
178 |
doc.rect(80, 20, 10, 10, 'FD') // filled square with red borders
|
|
|
179 |
|
|
|
180 |
doc.setDrawColor(0)
|
|
|
181 |
doc.setFillColor(255,0,0)
|
|
|
182 |
doc.rect(100, 20, 10, 10, 'F') // filled red square
|
|
|
183 |
|
|
|
184 |
doc.setDrawColor(0)
|
|
|
185 |
doc.setFillColor(255,0,0)
|
|
|
186 |
doc.rect(120, 20, 10, 10, 'FD') // filled red square with black borders
|
|
|
187 |
|
|
|
188 |
return doc.output()
|
|
|
189 |
}
|
|
|
190 |
, "009_demoliness.pdf":function(){
|
|
|
191 |
var doc = new jsPDF()
|
|
|
192 |
|
|
|
193 |
doc.line(20, 20, 60, 20) // horizontal line
|
|
|
194 |
|
|
|
195 |
doc.setLineWidth(0.5)
|
|
|
196 |
doc.line(20, 25, 60, 25)
|
|
|
197 |
|
|
|
198 |
doc.setLineWidth(1)
|
|
|
199 |
doc.line(20, 30, 60, 30)
|
|
|
200 |
|
|
|
201 |
doc.setLineWidth(1.5)
|
|
|
202 |
doc.line(20, 35, 60, 35)
|
|
|
203 |
|
|
|
204 |
doc.setDrawColor(255,0,0) // draw red lines
|
|
|
205 |
|
|
|
206 |
doc.setLineWidth(0.1)
|
|
|
207 |
doc.line(100, 20, 100, 60) // vertical line
|
|
|
208 |
|
|
|
209 |
doc.setLineWidth(0.5)
|
|
|
210 |
doc.line(105, 20, 105, 60)
|
|
|
211 |
|
|
|
212 |
doc.setLineWidth(1)
|
|
|
213 |
doc.line(110, 20, 110, 60)
|
|
|
214 |
|
|
|
215 |
doc.setLineWidth(1.5)
|
|
|
216 |
doc.line(115, 20, 115, 60)
|
|
|
217 |
|
|
|
218 |
return doc.output()
|
|
|
219 |
}
|
|
|
220 |
, "010_democircles.pdf":function(){
|
|
|
221 |
var doc = new jsPDF()
|
|
|
222 |
|
|
|
223 |
doc.ellipse(40, 20, 10, 5)
|
|
|
224 |
|
|
|
225 |
doc.setFillColor(0,0,255)
|
|
|
226 |
doc.ellipse(80, 20, 10, 5, 'F')
|
|
|
227 |
|
|
|
228 |
doc.setLineWidth(1)
|
|
|
229 |
doc.setDrawColor(0)
|
|
|
230 |
doc.setFillColor(255,0,0)
|
|
|
231 |
doc.circle(120, 20, 5, 'FD')
|
|
|
232 |
|
|
|
233 |
return doc.output()
|
|
|
234 |
}
|
|
|
235 |
, "011_multilinetext.pdf":function(){
|
|
|
236 |
var doc = new jsPDF()
|
|
|
237 |
, text = [
|
|
|
238 |
'This is line one'
|
|
|
239 |
, 'This is line two'
|
|
|
240 |
, 'This is line three'
|
|
|
241 |
, 'This is line four'
|
|
|
242 |
, 'This is line five'
|
|
|
243 |
]
|
|
|
244 |
doc.text(text, 20, 20)
|
|
|
245 |
return doc.output()
|
|
|
246 |
}
|
|
|
247 |
, "012_multiplelines.pdf":function(){
|
|
|
248 |
var doc = new jsPDF()
|
|
|
249 |
, x1 = 40
|
|
|
250 |
, y1 = 40
|
|
|
251 |
, lines = [
|
|
|
252 |
[10,10]
|
|
|
253 |
, [-20,10]
|
|
|
254 |
, [-15,5,-20,10,-30,15]
|
|
|
255 |
]
|
|
|
256 |
|
|
|
257 |
doc.lines(lines, x1, y1)
|
|
|
258 |
doc.lines(lines, x1, y1, [-1, -1])
|
|
|
259 |
doc.lines(lines, x1, y1, [0.5, -0.5])
|
|
|
260 |
doc.lines(lines, x1, y1, [-2, 2])
|
|
|
261 |
return doc.output()
|
|
|
262 |
}
|
|
|
263 |
}
|
|
|
264 |
, testrunner = function(reference_file_name, test_data_yielder){
|
|
|
265 |
asyncTest(reference_file_name, function() {
|
|
|
266 |
//QUnit.stop()
|
|
|
267 |
require(['text!'+reference_file_name])
|
|
|
268 |
.then(function(expectedtext){
|
|
|
269 |
QUnit.expect(1)
|
|
|
270 |
|
|
|
271 |
var output = test_data_yielder()
|
|
|
272 |
|
|
|
273 |
if (dump) {
|
|
|
274 |
displayInTextArea(output, reference_file_name)
|
|
|
275 |
QUnit.equal(true, true)
|
|
|
276 |
|
|
|
277 |
} else {
|
|
|
278 |
QUnit.equal(
|
|
|
279 |
removeMinorDiffs( output )
|
|
|
280 |
, removeMinorDiffs( expectedtext )
|
|
|
281 |
)
|
|
|
282 |
}
|
|
|
283 |
QUnit.start()
|
|
|
284 |
//stop()
|
|
|
285 |
})
|
|
|
286 |
})
|
|
|
287 |
}
|
|
|
288 |
|
|
|
289 |
////////////////////////////////////////////////////
|
|
|
290 |
// running homogenous tests
|
|
|
291 |
|
|
|
292 |
for (var filename in testinventory){
|
|
|
293 |
if (testinventory.hasOwnProperty(filename)){
|
|
|
294 |
testrunner(
|
|
|
295 |
filename
|
|
|
296 |
, testinventory[filename]
|
|
|
297 |
)
|
|
|
298 |
}
|
|
|
299 |
}
|
|
|
300 |
|
|
|
301 |
asyncTest('013_sillysvgrenderer', function() {
|
|
|
302 |
//QUnit.stop()
|
|
|
303 |
require(['text!013_sillysvgrenderer.svg', 'text!013_sillysvgrenderer.pdf'])
|
|
|
304 |
.then(function(svgtext, expectedtext){
|
|
|
305 |
QUnit.expect(1)
|
|
|
306 |
|
|
|
307 |
var pdf = jsPDF() // 'p','pt','letter')
|
|
|
308 |
|
|
|
309 |
pdf.addSVG(svgtext, 20, 20, pdf.internal.pageSize.width - 20*2)
|
|
|
310 |
|
|
|
311 |
// pdf.output('dataurl')
|
|
|
312 |
// window.mypdf = pdf.output('dataurlstring')
|
|
|
313 |
|
|
|
314 |
var output = pdf.output()
|
|
|
315 |
if (dump) {
|
|
|
316 |
displayInTextArea(output, '013_sillysvgrenderer')
|
|
|
317 |
QUnit.equal(true, true)
|
|
|
318 |
|
|
|
319 |
} else {
|
|
|
320 |
QUnit.equal(
|
|
|
321 |
removeMinorDiffs( output )
|
|
|
322 |
, removeMinorDiffs( expectedtext )
|
|
|
323 |
)
|
|
|
324 |
}
|
|
|
325 |
QUnit.start()
|
|
|
326 |
//stop()
|
|
|
327 |
})
|
|
|
328 |
})
|
|
|
329 |
|
|
|
330 |
// handcrafted tests
|
|
|
331 |
asyncTest('014_addImage', function() {
|
|
|
332 |
|
|
|
333 |
//QUnit.stop()
|
|
|
334 |
require(
|
|
|
335 |
['text!014_addImage.jpeg.base64.txt', 'text!014_addImage.pdf.base64.txt']
|
|
|
336 |
).then(function(base64encodedJpeg, base64encodedPDF){
|
|
|
337 |
QUnit.expect(2)
|
|
|
338 |
|
|
|
339 |
var pdf = jsPDF()
|
|
|
340 |
|
|
|
341 |
pdf.addImage(atob(base64encodedJpeg), 'jpeg', 20, 20)
|
|
|
342 |
|
|
|
343 |
QUnit.equal(
|
|
|
344 |
// just testing if it does not blow up.
|
|
|
345 |
pdf.output('datauristring') !== ''
|
|
|
346 |
, true
|
|
|
347 |
)
|
|
|
348 |
|
|
|
349 |
pdf = jsPDF()
|
|
|
350 |
|
|
|
351 |
pdf.addImage(atob(base64encodedJpeg), 'jpeg', 20, 20)
|
|
|
352 |
|
|
|
353 |
// window.pdfbase64 = btoa(pdf.output())
|
|
|
354 |
|
|
|
355 |
var output = pdf.output()
|
|
|
356 |
|
|
|
357 |
if (dump) {
|
|
|
358 |
displayInTextArea(output, '014_addImage')
|
|
|
359 |
|
|
|
360 |
QUnit.equal(true, true)
|
|
|
361 |
|
|
|
362 |
} else {
|
|
|
363 |
|
|
|
364 |
QUnit.equal(
|
|
|
365 |
removeMinorDiffs( output )
|
|
|
366 |
, removeMinorDiffs( atob(base64encodedPDF) )
|
|
|
367 |
)
|
|
|
368 |
}
|
|
|
369 |
QUnit.start()
|
|
|
370 |
//stop()
|
|
|
371 |
})
|
|
|
372 |
})
|
|
|
373 |
|
|
|
374 |
|
|
|
375 |
// handcrafted tests
|
|
|
376 |
asyncTest('015_splittext', function() {
|
|
|
377 |
|
|
|
378 |
//QUnit.stop()
|
|
|
379 |
require(
|
|
|
380 |
['015_splittext', 'text!015_splittext.pdf']
|
|
|
381 |
).then(function(runner, shouldbe){
|
|
|
382 |
QUnit.expect(1)
|
|
|
383 |
|
|
|
384 |
var pdf = runner(jsPDF)
|
|
|
385 |
|
|
|
386 |
var output = pdf.output()
|
|
|
387 |
if (dump) {
|
|
|
388 |
displayInTextArea(output, '015_splittext')
|
|
|
389 |
QUnit.equal(true, true)
|
|
|
390 |
|
|
|
391 |
} else {
|
|
|
392 |
QUnit.equal(
|
|
|
393 |
removeMinorDiffs( output )
|
|
|
394 |
, removeMinorDiffs( shouldbe )
|
|
|
395 |
)
|
|
|
396 |
}
|
|
|
397 |
QUnit.start()
|
|
|
398 |
//stop()
|
|
|
399 |
})
|
|
|
400 |
})
|
|
|
401 |
|
|
|
402 |
|
|
|
403 |
}) // end of document.ready(
|
|
|
404 |
|
|
|
405 |
|