Skip to content

Commit ec65985

Browse files
committed
Merge pull request #406 from Gavvers/text-align-new
Text Alignment Feature
2 parents 2204746 + 10caf31 commit ec65985

File tree

3 files changed

+104
-8
lines changed

3 files changed

+104
-8
lines changed

examples/basic.html

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,28 @@ <h2></h2>
342342
</pre>
343343
<button onclick="javascript:demoFromHTML()" class="button">Run Code</button></p></div></div>
344344

345+
346+
<h2><a href="#">Text alignment</a></h2>
347+
<div><p><pre>var pdf = new jsPDF('p', 'pt', 'letter');
348+
349+
pdf.text( 'This text is normally\raligned.', 140, 50 );
350+
351+
pdf.text( 'This text is centered\raround\rthis point.', 140, 120, 'center' );
352+
353+
pdf.text( 'This text is rotated\rand centered around\rthis point.', 140, 300, 45, 'center' );
354+
355+
pdf.text( 'This text is\raligned to the\rright.', 140, 400, 'right' );
356+
357+
pdf.text( 'This text is\raligned to the\rright.', 140, 550, 45, 'right' );
358+
359+
pdf.text( 'This single line is centered', 460, 50, 'center' );
360+
361+
pdf.text( 'This right aligned text\r\rhas an empty line.', 460, 200, 'right' );
362+
363+
364+
pdf.save('Test.pdf');</pre>
365+
<a href="javascript:demoTextAlign()" class="button">Run Code</a></p></div>
366+
345367
</div>
346368
</div>
347369

examples/js/basic.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,3 +351,32 @@ function demoFromHTML() {
351351
margins
352352
)
353353
}
354+
355+
function demoTextAlign() {
356+
var pdf = new jsPDF('p', 'pt', 'letter');
357+
358+
pdf.setFillColor(0);
359+
pdf.circle( 140, 50, 2, "F" );
360+
pdf.text( 'This text is normally\raligned.', 140, 50 );
361+
362+
pdf.circle( 140, 120, 2, "F" );
363+
pdf.text( 'This text is centered\raround\rthis point.', 140, 120, 'center' );
364+
365+
pdf.circle( 140, 300, 2, "F" );
366+
pdf.text( 'This text is rotated\rand centered around\rthis point.', 140, 300, 45, 'center' );
367+
368+
pdf.circle( 140, 400, 2, "F" );
369+
pdf.text( 'This text is\raligned to the\rright.', 140, 400, 'right' );
370+
371+
pdf.circle( 140, 550, 2, "F" );
372+
pdf.text( 'This text is\raligned to the\rright.', 140, 550, 45, 'right' );
373+
374+
pdf.circle( 460, 50, 2, "F" );
375+
pdf.text( 'This single line is centered', 460, 50, 'center' );
376+
377+
pdf.circle( 460, 200, 2, "F" );
378+
pdf.text( 'This right aligned text\r\rhas an empty line.', 460, 200, 'right' );
379+
380+
381+
pdf.save('Test.pdf');
382+
}

jspdf.js

Lines changed: 53 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,7 +1053,7 @@ var jsPDF = (function(global) {
10531053
* @methodOf jsPDF#
10541054
* @name text
10551055
*/
1056-
API.text = function(text, x, y, flags, angle) {
1056+
API.text = function(text, x, y, flags, angle, align) {
10571057
/**
10581058
* Inserts something like this into PDF
10591059
* BT
@@ -1087,8 +1087,22 @@ var jsPDF = (function(global) {
10871087
// the user wanted to print multiple lines, so break the
10881088
// text up into an array. If the text is already an array,
10891089
// we assume the user knows what they are doing.
1090-
if (typeof text === 'string' && text.match(/[\n\r]/)) {
1091-
text = text.split(/\r\n|\r|\n/g);
1090+
if (typeof text === 'string') {
1091+
if(text.match(/[\n\r]/)) {
1092+
text = text.split( /\r\n|\r|\n/g);
1093+
} else {
1094+
// Convert text into an array anyway
1095+
// to simplify later code.
1096+
text = [text];
1097+
}
1098+
}
1099+
if (typeof angle === 'string') {
1100+
align = angle;
1101+
angle = null;
1102+
}
1103+
if (typeof flags === 'string') {
1104+
align = flags;
1105+
flags = null;
10921106
}
10931107
if (typeof flags === 'number') {
10941108
angle = flags;
@@ -1124,11 +1138,9 @@ var jsPDF = (function(global) {
11241138
this.lastTextWasStroke = false;
11251139
}
11261140

1127-
if (typeof text === 'string') {
1128-
text = ESC(text);
1129-
} else if (text instanceof Array) {
1141+
if (text instanceof Array) {
11301142
// we don't want to destroy original text array, so cloning it
1131-
var sa = text.concat(), da = [], len = sa.length;
1143+
var sa = text.concat(), da = [], i, len = sa.length;
11321144
// we do array.join('text that must not be PDFescaped")
11331145
// thus, pdfEscape each component separately
11341146
while (len--) {
@@ -1138,7 +1150,40 @@ var jsPDF = (function(global) {
11381150
if (0 <= linesLeft && linesLeft < da.length + 1) {
11391151
todo = da.splice(linesLeft-1);
11401152
}
1141-
text = da.join(") Tj\nT* (");
1153+
1154+
if( align ) {
1155+
var prevX,
1156+
leading = activeFontSize * lineHeightProportion,
1157+
lineWidths = text.map( function( v ) {
1158+
return this.getStringUnitWidth( v ) * activeFontSize / k;
1159+
}, this );
1160+
// The first line uses the "main" Td setting,
1161+
// and the subsequent lines are offset by the
1162+
// previous line's x coordinate.
1163+
if( align === "center" ) {
1164+
// The passed in x coordinate defines
1165+
// the center point.
1166+
x -= lineWidths[0] / 2;
1167+
} else if ( align === "right" ) {
1168+
// The passed in x coordinate defines the
1169+
// rightmost point of the text.
1170+
x -= lineWidths[0];
1171+
} else {
1172+
throw new Error('Unrecognized alignment option, use "center" or "right".');
1173+
}
1174+
prevX = x;
1175+
text = da[0];
1176+
for ( i = 1, len = da.length ; i < len; i++ ) {
1177+
var delta = lineWidths[i-1] - lineWidths[i];
1178+
if( align === "center" ) delta /= 2;
1179+
// T* = x-offset leading Td ( text )
1180+
// PDF Spec 1.3 p.288
1181+
text += ") Tj\n" + delta + " -" + leading + " Td (" + da[i];
1182+
prevX += delta;
1183+
}
1184+
} else {
1185+
text = da.join(") Tj\nT* (");
1186+
}
11421187
} else {
11431188
throw new Error('Type of text must be string or Array. "' + text + '" is not recognized.');
11441189
}

0 commit comments

Comments
 (0)