Pietro Pietro - 3 years ago 235
Javascript Question

jsPDF justify text

I'm trying to apply some changes on jsPDF library to be able to justify text.

I'm having trouble to find the right value for Tw (word spacing).

In jspdf.js (L:1413) I have added this code:

if (align) {
...
else if (align === 'justify') {
left = x;
}
else {
throw new Error('Unrecognized alignment option, use "center" or "right".');
}
prevX = x;
text = '(' + da[0];

let pdfPageWidth = this.internal.pageSize.width;
let wordSpacing;
if( align === 'justify' ) {
let fontSize = this.internal.getFontSize();
let nWords = da[0].trim().split(/\s+/).length;
let textWidth = this.getStringUnitWidth(da[0].replace(/\s+/g, '')) / this.internal.scaleFactor;
wordSpacing = (Math.max(0, (pdfPageWidth - textWidth) / Math.max(1, nWords - 1));
wordSpacing += ' Tw\n';
text = wordSpacing + text;
}
...
}


The idea was to extract the space width by doing (pageWidth - textWidth) / numberOfWords -1. I can't get the correct word space.

Output example

BT
/F1 16 Tf
18.4 TL
0 g
28.35 756.85 Td
19.00357142857142 Tw
(And a little bit it adélkfjalké.) Tj
ET


Is there an encoding problem?

Thanks for your help.

Answer Source

After many tries I have found the working code solution :D. It works also with array of text as param.

        } else if (align === 'justify') {
          left = x;
        }
        else {
          throw new Error(
            'Unrecognized alignment option, use "center" or "right".'
          );
        }
        prevX = x;
        text = '(' + da[0];

        var pdfPageWidth = this.internal.pageSize.width;
        var wordSpacing;
        var fontSize = this.internal.getFontSize();
        if( align === 'justify' ) {
          var nWords = da[0].trim().split(/\s+/).length;
          var textWidth = this.getStringUnitWidth(da[0]) * fontSize / k;

          wordSpacing = (Math.max(0, ((pdfPageWidth - x - marginRight) - textWidth) / Math.max(1, nWords - 1))) * k;
          // Do not justify if wordSpacing is too high
          wordSpacing = ( wordSpacing > 50 ? 0 : wordSpacing ) + ' Tw\n';

          text = wordSpacing + text;
        }

        for (var i = 1, len = da.length; i < len; i++) {
          var delta = maxLineLength - lineWidths[i];
          if (align === "center") delta /= 2;
          if (align === "justify") { // TODO: improve code duplication
            delta = 0;
            var nWords = da[i].trim().split(/\s+/).length;
            var textWidth = this.getStringUnitWidth(da[i]) * fontSize / k;

            wordSpacing = (Math.max(0, ((pdfPageWidth - x - marginRight) - textWidth) / Math.max(1, nWords - 1))) * k;
            // Do not justify if wordSpacing is too high
            wordSpacing = ( wordSpacing > 50 ? 0 : wordSpacing ) + ' Tw\n';
            text += ") Tj\n" + ((left - prevX) + delta) + " -" + leading + " Td\n" + wordSpacing + "(" + da[i];
          } else {
            // T* = x-offset leading Td ( text )
            text += ") Tj\n" + ((left - prevX) + delta) + " -" + leading + " Td (" + da[i];
          }
          prevX = left + delta;
        }
      } else {
        text = ' 0 Tw\n (' + da.join(") Tj\nT* (");
      }

Here is my PR

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download