Skip to content

Commit 47f6864

Browse files
committed
Create jspdf\jspdf.js
1 parent a960b6b commit 47f6864

File tree

1 file changed

+304
-0
lines changed

1 file changed

+304
-0
lines changed

jspdf/jspdf\jspdf.js

Lines changed: 304 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,304 @@
1+
2+
/**
3+
* jsPDF
4+
* (c) 2009 James Hall
5+
*
6+
* Some parts based on FPDF.
7+
*/
8+
9+
var jsPDF = function(){
10+
11+
// Private properties
12+
var version = '20090504';
13+
var buffer = '';
14+
15+
var pdfVersion = '1.3'; // PDF Version
16+
var defaultPageFormat = 'a4';
17+
var pageFormats = { // Size in mm of various paper formats
18+
'a3': [841.89, 1190.55],
19+
'a4': [595.28, 841.89],
20+
'a5': [420.94, 595.28],
21+
'letter': [612, 792],
22+
'legal': [612, 1008]
23+
};
24+
var textColor = '0 g';
25+
var page = 0;
26+
var objectNumber = 2; // 'n' Current object number
27+
var state = 0; // Current document state
28+
var pages = new Array();
29+
var offsets = new Array(); // List of offsets
30+
var lineWidth = 0.200025; // 2mm
31+
var pageHeight;
32+
var k; // Scale factor
33+
var unit = 'mm'; // Default to mm for units
34+
var fontNumber; // TODO: This is temp, replace with real font handling
35+
var documentProperties = {};
36+
var fontSize = 16; // Default font size
37+
var pageFontSize = 16;
38+
39+
// Initilisation
40+
if (unit == 'pt') {
41+
k = 1;
42+
} else if(unit == 'mm') {
43+
k = 72/25.4;
44+
} else if(unit == 'cm') {
45+
k = 72/2.54;
46+
} else if(unit == 'in') {
47+
k = 72;
48+
}
49+
50+
// Private functions
51+
var newObject = function() {
52+
//Begin a new object
53+
objectNumber ++;
54+
offsets[objectNumber] = buffer.length;
55+
out(objectNumber + ' 0 obj');
56+
}
57+
58+
59+
var putHeader = function() {
60+
out('%PDF-' + pdfVersion);
61+
}
62+
63+
var putPages = function() {
64+
65+
// TODO: Fix, hardcoded to a4 portrait
66+
var wPt = pageWidth * k;
67+
var hPt = pageHeight * k;
68+
69+
for(n=1; n <= page; n++) {
70+
newObject();
71+
out('<</Type /Page');
72+
out('/Parent 1 0 R');
73+
out('/Resources 2 0 R');
74+
out('/Contents ' + (objectNumber + 1) + ' 0 R>>');
75+
out('endobj');
76+
77+
//Page content
78+
p = pages[n];
79+
newObject();
80+
out('<</Length ' + p.length + '>>');
81+
putStream(p);
82+
out('endobj');
83+
}
84+
offsets[1] = buffer.length;
85+
out('1 0 obj');
86+
out('<</Type /Pages');
87+
var kids='/Kids [';
88+
for (i = 0; i < page; i++) {
89+
kids += (3 + 2 * i) + ' 0 R ';
90+
}
91+
out(kids + ']');
92+
out('/Count ' + page);
93+
out(sprintf('/MediaBox [0 0 %.2f %.2f]', wPt, hPt));
94+
out('>>');
95+
out('endobj');
96+
}
97+
98+
var putStream = function(str) {
99+
out('stream');
100+
out(str);
101+
out('endstream');
102+
}
103+
104+
var putResources = function() {
105+
putFonts();
106+
putImages();
107+
108+
//Resource dictionary
109+
offsets[2] = buffer.length;
110+
out('2 0 obj');
111+
out('<<');
112+
putResourceDictionary();
113+
out('>>');
114+
out('endobj');
115+
}
116+
117+
var putFonts = function() {
118+
// TODO: Only supports core font hardcoded to Helvetica
119+
newObject();
120+
fontNumber = objectNumber;
121+
name = 'Helvetica';
122+
out('<</Type /Font');
123+
out('/BaseFont /' + name);
124+
out('/Subtype /Type1');
125+
out('/Encoding /WinAnsiEncoding');
126+
out('>>');
127+
out('endobj');
128+
}
129+
130+
var putImages = function() {
131+
// TODO
132+
}
133+
134+
var putResourceDictionary = function() {
135+
out('/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]');
136+
out('/Font <<');
137+
// Do this for each font, the '1' bit is the index of the font
138+
// fontNumber is currently the object number related to 'putFonts'
139+
out('/F1 ' + fontNumber + ' 0 R');
140+
out('>>');
141+
out('/XObject <<');
142+
putXobjectDict();
143+
out('>>');
144+
}
145+
146+
var putXobjectDict = function() {
147+
// TODO
148+
// Loop through images
149+
}
150+
151+
152+
var putInfo = function() {
153+
out('/Producer (jsPDF ' + version + ')');
154+
if(documentProperties.title != undefined) {
155+
out('/Title (' + pdfEscape(documentProperties.title) + ')');
156+
}
157+
if(documentProperties.subject != undefined) {
158+
out('/Subject (' + pdfEscape(documentProperties.subject) + ')');
159+
}
160+
if(documentProperties.author != undefined) {
161+
out('/Author (' + pdfEscape(documentProperties.author) + ')');
162+
}
163+
if(documentProperties.keywords != undefined) {
164+
out('/Keywords (' + pdfEscape(documentProperties.keywords) + ')');
165+
}
166+
if(documentProperties.creator != undefined) {
167+
out('/Creator (' + pdfEscape(documentProperties.creator) + ')');
168+
}
169+
var created = new Date();
170+
var year = created.getFullYear();
171+
var month = (created.getMonth() + 1);
172+
var day = created.getDate();
173+
var hour = created.getHours();
174+
var minute = created.getMinutes();
175+
var second = created.getSeconds();
176+
out('/CreationDate (D:' + sprintf('%02d%02d%02d%02d%02d%02d', year, month, day, hour, minute, second) + ')');
177+
}
178+
179+
var putCatalog = function () {
180+
out('/Type /Catalog');
181+
out('/Pages 1 0 R');
182+
// TODO: Add zoom and layout modes
183+
out('/OpenAction [3 0 R /FitH null]');
184+
out('/PageLayout /OneColumn');
185+
}
186+
187+
function putTrailer() {
188+
out('/Size ' + (objectNumber + 1));
189+
out('/Root ' + objectNumber + ' 0 R');
190+
out('/Info ' + (objectNumber - 1) + ' 0 R');
191+
}
192+
193+
var endDocument = function() {
194+
state = 1;
195+
putHeader();
196+
putPages();
197+
198+
putResources();
199+
//Info
200+
newObject();
201+
out('<<');
202+
putInfo();
203+
out('>>');
204+
out('endobj');
205+
206+
//Catalog
207+
newObject();
208+
out('<<');
209+
putCatalog();
210+
out('>>');
211+
out('endobj');
212+
213+
//Cross-ref
214+
var o = buffer.length;
215+
out('xref');
216+
out('0 ' + (objectNumber + 1));
217+
out('0000000000 65535 f ');
218+
for (var i=1; i <= objectNumber; i++) {
219+
out(sprintf('%010d 00000 n ', offsets[i]));
220+
}
221+
//Trailer
222+
out('trailer');
223+
out('<<');
224+
putTrailer();
225+
out('>>');
226+
out('startxref');
227+
out(o);
228+
out('%%EOF');
229+
state = 3;
230+
}
231+
232+
var beginPage = function() {
233+
page ++;
234+
// Do dimension stuff
235+
state = 2;
236+
pages[page] = '';
237+
238+
// TODO: Hardcoded at A4 and portrait
239+
pageHeight = pageFormats['a4'][1] / k;
240+
pageWidth = pageFormats['a4'][0] / k;
241+
}
242+
243+
var out = function(string) {
244+
if(state == 2) {
245+
pages[page] += string + '\n';
246+
} else {
247+
buffer += string + '\n';
248+
}
249+
}
250+
251+
var _addPage = function() {
252+
beginPage();
253+
// Set line width
254+
out(sprintf('%.2f w', (lineWidth * k)));
255+
256+
// Set font - TODO
257+
// 16 is the font size
258+
pageFontSize = fontSize;
259+
out('BT /F1 ' + parseInt(fontSize) + '.00 Tf ET');
260+
}
261+
262+
// Add the first page automatically
263+
_addPage();
264+
265+
// Escape text
266+
var pdfEscape = function(text) {
267+
return text.replace(/\\/g, '\\\\').replace(/\(/g, '\\(').replace(/\)/g, '\\)');
268+
}
269+
270+
return {
271+
addPage: function() {
272+
_addPage();
273+
},
274+
text: function(x, y, text) {
275+
// need page height
276+
if(pageFontSize != fontSize) {
277+
out('BT /F1 ' + parseInt(fontSize) + '.00 Tf ET');
278+
pageFontSize = fontSize;
279+
}
280+
var str = sprintf('BT %.2f %.2f Td (%s) Tj ET', x * k, (pageHeight - y) * k, pdfEscape(text));
281+
out(str);
282+
},
283+
setProperties: function(properties) {
284+
documentProperties = properties;
285+
},
286+
addImage: function(imageData, format, x, y, w, h) {
287+
288+
},
289+
output: function(type, options) {
290+
endDocument();
291+
if(type == undefined) {
292+
return buffer;
293+
}
294+
if(type == 'datauri') {
295+
document.location.href = 'data:application/pdf;base64,' + Base64.encode(buffer);
296+
}
297+
// @TODO: Add different output options
298+
},
299+
setFontSize: function(size) {
300+
fontSize = size;
301+
}
302+
}
303+
304+
};

0 commit comments

Comments
 (0)