@@ -979,7 +979,7 @@ var jsPDF = (function(global) {
979
979
* @methodOf jsPDF#
980
980
* @name text
981
981
*/
982
- API . text = function ( text , x , y , flags , angle ) {
982
+ API . text = function ( text , x , y , flags , angle , align ) {
983
983
/**
984
984
* Inserts something like this into PDF
985
985
* BT
@@ -1013,8 +1013,22 @@ var jsPDF = (function(global) {
1013
1013
// the user wanted to print multiple lines, so break the
1014
1014
// text up into an array. If the text is already an array,
1015
1015
// we assume the user knows what they are doing.
1016
- if ( typeof text === 'string' && text . match ( / [ \n \r ] / ) ) {
1017
- text = text . split ( / \r \n | \r | \n / g) ;
1016
+ // Convert text into an array anyway to simplify
1017
+ // later code.
1018
+ if ( typeof text === 'string' ) {
1019
+ if ( text . match ( / [ \n \r ] / ) ) {
1020
+ text = text . split ( / \r \n | \r | \n / g) ;
1021
+ } else {
1022
+ text = [ text ] ;
1023
+ }
1024
+ }
1025
+ if ( typeof angle === 'string' ) {
1026
+ align = angle ;
1027
+ angle = null ;
1028
+ }
1029
+ if ( typeof flags === 'string' ) {
1030
+ align = flags ;
1031
+ flags = null ;
1018
1032
}
1019
1033
if ( typeof flags === 'number' ) {
1020
1034
angle = flags ;
@@ -1034,11 +1048,9 @@ var jsPDF = (function(global) {
1034
1048
if ( ! ( 'autoencode' in flags ) )
1035
1049
flags . autoencode = true ;
1036
1050
1037
- if ( typeof text === 'string' ) {
1038
- text = ESC ( text ) ;
1039
- } else if ( text instanceof Array ) {
1051
+ if ( text instanceof Array ) {
1040
1052
// we don't want to destroy original text array, so cloning it
1041
- var sa = text . concat ( ) , da = [ ] , len = sa . length ;
1053
+ var sa = text . concat ( ) , da = [ ] , i , len = sa . length ;
1042
1054
// we do array.join('text that must not be PDFescaped")
1043
1055
// thus, pdfEscape each component separately
1044
1056
while ( len -- ) {
@@ -1048,7 +1060,47 @@ var jsPDF = (function(global) {
1048
1060
if ( 0 <= linesLeft && linesLeft < da . length + 1 ) {
1049
1061
todo = da . splice ( linesLeft - 1 ) ;
1050
1062
}
1051
- text = da . join ( ") Tj\nT* (" ) ;
1063
+
1064
+ if ( align ) {
1065
+ var left ,
1066
+ prevX ,
1067
+ maxLineLength ,
1068
+ leading = activeFontSize * lineHeightProportion ,
1069
+ lineWidths = text . map ( function ( v ) {
1070
+ return this . getStringUnitWidth ( v ) * activeFontSize / k ;
1071
+ } , this ) ;
1072
+ maxLineLength = Math . max . apply ( Math , lineWidths ) ;
1073
+ // The first line uses the "main" Td setting,
1074
+ // and the subsequent lines are offset by the
1075
+ // previous line's x coordinate.
1076
+ if ( align === "center" ) {
1077
+ // The passed in x coordinate defines
1078
+ // the center point.
1079
+ left = x - maxLineLength / 2 ;
1080
+ x -= lineWidths [ 0 ] / 2 ;
1081
+ } else if ( align === "right" ) {
1082
+ // The passed in x coordinate defines the
1083
+ // rightmost point of the text.
1084
+ left = x - maxLineLength ;
1085
+ x -= lineWidths [ 0 ] ;
1086
+ } else {
1087
+ throw new Error ( 'Unrecognized alignment option, use "center" or "right".' ) ;
1088
+ }
1089
+ prevX = x ;
1090
+ text = da [ 0 ] + ") Tj\n" ;
1091
+ for ( i = 1 , len = da . length ; i < len ; i ++ ) {
1092
+ var delta = maxLineLength - lineWidths [ i ] ;
1093
+ if ( align === "center" ) delta /= 2 ;
1094
+ // T* = x-offset leading Td ( text )
1095
+ text += ( ( left - prevX ) + delta ) + " -" + leading + " Td (" + da [ i ] ;
1096
+ prevX = left + delta ;
1097
+ if ( i < len - 1 ) {
1098
+ text += ") Tj\n" ;
1099
+ }
1100
+ }
1101
+ } else {
1102
+ text = da . join ( ") Tj\nT* (" ) ;
1103
+ }
1052
1104
} else {
1053
1105
throw new Error ( 'Type of text must be string or Array. "' + text + '" is not recognized.' ) ;
1054
1106
}
0 commit comments