In pdf-lib, it is possible to auto-word-wrap text using a technique outlined here: /a/77436904/1766230
<code>import { PDFDocument, StandardFonts } from 'pdf-lib';
const doc = await PDFDocument.create();
const font = await doc.embedFont(StandardFonts.TimesRoman);
const page = doc.addPage();
// This will word-wrap fine:
page.drawText(someLongText, { font, size: 20, lineHeight: 25, maxWidth: 200, wordBreaks: [' '] });
// But now what?
// page.moveDown(???);
</code>
<code>import { PDFDocument, StandardFonts } from 'pdf-lib';
const doc = await PDFDocument.create();
const font = await doc.embedFont(StandardFonts.TimesRoman);
const page = doc.addPage();
// This will word-wrap fine:
page.drawText(someLongText, { font, size: 20, lineHeight: 25, maxWidth: 200, wordBreaks: [' '] });
// But now what?
// page.moveDown(???);
</code>
import { PDFDocument, StandardFonts } from 'pdf-lib';
const doc = await PDFDocument.create();
const font = await doc.embedFont(StandardFonts.TimesRoman);
const page = doc.addPage();
// This will word-wrap fine:
page.drawText(someLongText, { font, size: 20, lineHeight: 25, maxWidth: 200, wordBreaks: [' '] });
// But now what?
// page.moveDown(???);
The problem is you may need to either…
- Move the y cursor down so that you can write the next line to the page. (
page.moveDown
) - Detect when a new page might be needed — i.e., the height of this wrapped text would go off the bottom of the page — so that you can split up the text and add a new page (
doc.addPage
).
But there does not seem to be any functions in the documentation that let’s you determine the height of the word-wrapped text you are drawing to the page. font.heightAtSize(size)
just gets the height of the font. What can be done?
0
I figured out a solution after looking into the code for drawText
.
There is a utility function called breakTextIntoLines
, that we’ll need to run again to get the number of lines.
<code>import { breakTextIntoLines } from 'pdf-lib';
//
// ... define font, doc, page ...
//
function wordWrapHeight(text, options) {
const { font, size, lineHeight, wordBreaks, maxWidth } = options;
const getTextWidth = (t) => font.widthOfTextAtSize(t, size);
const lines = breakTextIntoLines(text, wordBreaks, maxWidth, getTextWidth);
return lines.length * lineHeight;
}
const size = 20;
const lineHeight = size * 1.4;
const maxWidth = 200;
const wordBreaks = [' '];
const options = { size, lineHeight, font, maxWidth, wordBreaks };
const distanceDown = wordWrapHeight(text, options);
const y = page.getY();
const endY = y - distanceDown;
// TODO: Determine if the endY would take you off the page.
// If so, then split the lines up based on the amount of room left.
// Otherwise, you do this:
page.drawText(text, options);
page.moveDown(distanceDown);
</code>
<code>import { breakTextIntoLines } from 'pdf-lib';
//
// ... define font, doc, page ...
//
function wordWrapHeight(text, options) {
const { font, size, lineHeight, wordBreaks, maxWidth } = options;
const getTextWidth = (t) => font.widthOfTextAtSize(t, size);
const lines = breakTextIntoLines(text, wordBreaks, maxWidth, getTextWidth);
return lines.length * lineHeight;
}
const size = 20;
const lineHeight = size * 1.4;
const maxWidth = 200;
const wordBreaks = [' '];
const options = { size, lineHeight, font, maxWidth, wordBreaks };
const distanceDown = wordWrapHeight(text, options);
const y = page.getY();
const endY = y - distanceDown;
// TODO: Determine if the endY would take you off the page.
// If so, then split the lines up based on the amount of room left.
// Otherwise, you do this:
page.drawText(text, options);
page.moveDown(distanceDown);
</code>
import { breakTextIntoLines } from 'pdf-lib';
//
// ... define font, doc, page ...
//
function wordWrapHeight(text, options) {
const { font, size, lineHeight, wordBreaks, maxWidth } = options;
const getTextWidth = (t) => font.widthOfTextAtSize(t, size);
const lines = breakTextIntoLines(text, wordBreaks, maxWidth, getTextWidth);
return lines.length * lineHeight;
}
const size = 20;
const lineHeight = size * 1.4;
const maxWidth = 200;
const wordBreaks = [' '];
const options = { size, lineHeight, font, maxWidth, wordBreaks };
const distanceDown = wordWrapHeight(text, options);
const y = page.getY();
const endY = y - distanceDown;
// TODO: Determine if the endY would take you off the page.
// If so, then split the lines up based on the amount of room left.
// Otherwise, you do this:
page.drawText(text, options);
page.moveDown(distanceDown);