pdf-lib icon indicating copy to clipboard operation
pdf-lib copied to clipboard

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

Open Stophface opened this issue 1 year ago • 2 comments

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

  • [X] My report includes a Short, Self Contained, Correct (Compilable) Example.
  • [X] I have attached all PDFs, images, and other files needed to run my SSCCE.

Additional Notes

No response

Stophface avatar Dec 13 '23 12:12 Stophface

I am facing the same issue. This fails

    page.drawText(customTextWithNewLine, {
      x: textX,
      y: textY,
      size: fontSize,
      font,
    });

ephraimduncan avatar Feb 17 '24 09:02 ephraimduncan

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.

bryandidur avatar Mar 07 '24 16:03 bryandidur