Hopding / pdf-lib

Create and modify PDF documents in any JavaScript environment
https://pdf-lib.js.org
MIT License
6.6k stars 635 forks source link

Getting unexpected Error: WinAnsi cannot encode " " (0x000a) #1570

Open Stophface opened 7 months ago

Stophface commented 7 months ago

What were you trying to do?

I am trying to add a \n to my text to create a line break. The text then should be drawn onto the page with page.drawText().

How did you attempt to do it?

Pretty straight foward

const generateText = (foo: string[]) => {
    return foo.map(bar => `${bar} \n`).join("")
}

I then try to draw this

const pdfDoc = await PDFDocument.create()
let page = pdfDoc.addPage()
const fontNormal = await pdfDoc.embedFont(StandardFonts.Helvetica)
const pageMarginRight = 50;
const {width, height} = page.getSize()
const fontSize = 9

const someTextArray = ["abc", "def", "ghi"]
const text = generateText(someTextArray)
page.drawText(text, {
    x: width - pageMarginRight - fontNormal.widthOfTextAtSize(text, fontSize),
    y: 10,
    size: fontSize
    lineHeight: 10
    font: fontNormal,
    color: black,
})

What actually happened?

I get the error

Uncaught (in promise) Error: WinAnsi cannot encode " " (0x000a) node_modules bundle.js:69129 encodeTextAsGlyphs StandardFontEmbedder.ts:124 widthOfTextAtSize StandardFontEmbedder.ts:59 widthOfTextAtSize PDFFont.ts:89 foo.ts:174...

What did you expect to happen?

I expect to be able to add \n to the text to insert a line break. The thing I do not understand is, I am pretty much doing the same in this function

const wrapText = (text: string, width: number, font: PDFFont, fontSize: number, separator: string) => {
    const words = text.split(separator);
    let line = '';
    let result = '';
    let countTextLines = 1
    for (let n = 0; n < words.length; n++) {
        const testLine = line + words[n] + ' ';
        const testWidth = font.widthOfTextAtSize(testLine, fontSize);
        if (testWidth > width) {
            result += line + '\n';
            line = words[n] + ' ';
            countTextLines += 1
        } else {
            line = testLine;
        }
    }
    result += line;
    return {text: result, countTextLines};
}

The result of

result = wrapText(...)

I can draw on the page

   page.drawText(result.text, {
        x: width - pageMarginRight - fontNormal.widthOfTextAtSize(text, fontSize),
        y: 10,
        size: fontSize
        lineHeight: 10
        font: fontNormal,
        color: black,
    })

without getting an error, eventhouh in wrapText() I add an \n.

How can we reproduce the issue?


const someTextArray = ["abc", "def", "ghi"]

const generateText = (foo: string[]) => {
    return foo.map(bar => `${bar} \n`).join("")
}

export const wrapText = (text: string, width: number, font: PDFFont, fontSize: number, separator: string) => {
    const words = text.split(separator);
    let line = '';
    let result = '';
    let countTextLines = 1
    for (let n = 0; n < words.length; n++) {
        const testLine = line + words[n] + ' ';
        const testWidth = font.widthOfTextAtSize(testLine, fontSize);
        if (testWidth > width) {
            result += line + '\n';
            line = words[n] + ' ';
            countTextLines += 1
        } else {
            line = testLine;
        }
    }
    result += line;
    return {text: result, countTextLines};
}

const pdfDoc = await PDFDocument.create()
let page = pdfDoc.addPage()
const fontNormal = await pdfDoc.embedFont(StandardFonts.Helvetica)
const pageMarginRight = 50;
const {width, height} = page.getSize()
const fontSize = 9

// this is not working
const notWorkingText = generateText(someTextArray)
page.drawText(notWorkingText, {
    x: width - pageMarginRight - fontNormal.widthOfTextAtSize(text, fontSize),
    y: 10,
    size: fontSize
    lineHeight: 10
    font: fontNormal,
    color: black,
})

// this is working
const workingText = wrapText(someTextArray, width, fontNormal, fontSize, "")
 page.drawText(workingText.text, {
      x: width - pageMarginRight - fontNormal.widthOfTextAtSize(text, fontSize),
      y: 10,
      size: fontSize
      lineHeight: 10
      font: fontNormal,
      color: black,
  })

Version

1.17.1

What environment are you running pdf-lib in?

Browser

Checklist

Additional Notes

No response

ephraimduncan commented 5 months ago

I am facing the same issue. This fails

    page.drawText(customTextWithNewLine, {
      x: textX,
      y: textY,
      size: fontSize,
      font,
    });
bryandidur commented 4 months ago

I faced a similar error with character encoding. But understanding the problem with the documentation and using the Noto font instead of the default fonts, works for me.