pdf-lib-extended 1.0.19 → 1.0.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pdf-lib-extended",
3
- "version": "1.0.19",
3
+ "version": "1.0.20",
4
4
  "description": "This project extends the capabilities of the pdf-lib JavaScript library by providing a set of helper functions that simplify common PDF manipulation tasks. It includes utilities for drawing and formatting text, images, and shapes within PDF documents, allowing for more advanced customization and automation. The class-based architecture, designed as a toolkit, ensures that developers can easily integrate these enhanced features into their existing workflows. With this extension, users can streamline the creation of dynamic and complex PDFs with minimal effort.",
5
5
  "main": "index.js",
6
6
  "repository": {
@@ -464,69 +464,69 @@ class PDFLibExtended {
464
464
  * @param {import('pdf-lib').RGB} options.color - The color of the text
465
465
  * @param {number} options.opacity - The opacity of the text
466
466
  */
467
- drawParagraph(text, options = {}) {
468
- let defaultOptions = {
467
+ drawParagraph(pdf, text, options = {}) {
468
+ const defaultOptions = {
469
469
  align: "left",
470
470
  range: {
471
- left: this.getMargin().left,
472
- right: this.getCurrentPage().getWidth() - this.getMargin().right
471
+ left: pdf.getMargin().left,
472
+ right: pdf.getCurrentPage().getWidth() - pdf.getMargin().right
473
473
  },
474
- size: this.getTextSize(),
475
- color: this.getColor(),
474
+ size: pdf.getTextSize(),
475
+ color: pdf.getColor(),
476
476
  opacity: 1,
477
- padding: 0,
477
+ padding: 0, // extra spacing between lines
478
478
  wordWrap: true,
479
479
  characterWrap: false,
480
480
  ...options
481
481
  };
482
- if(options.range) this.getCurrentPage().moveTo(defaultOptions.range.left, this.getCurrentPage().getY());
483
482
 
484
- let maxWidth = defaultOptions.range.right - defaultOptions.range.left;
485
- let currentWidth = 0;
486
- let currentLine = "";
487
-
488
- if(defaultOptions.wordWrap){
489
- text = text.split(" ");
490
- }else{
491
- text = text.split("");
492
- }
483
+ // Always move to paragraph start (left edge of range)
484
+ pdf.getCurrentPage().moveTo(defaultOptions.range.left, pdf.getCurrentPage().getY());
493
485
 
494
- text.forEach((string, i) => {
495
- let wordWidth = this.getCurrentFont().widthOfTextAtSize(string, defaultOptions.size);
486
+ const maxWidth = defaultOptions.range.right - defaultOptions.range.left;
496
487
 
497
- // Check if adding this word would overflow
498
- if (currentWidth + wordWidth > maxWidth) {
499
- this.drawText(currentLine.trim(), {
500
- size: defaultOptions.size,
501
- color: defaultOptions.color,
502
- opacity: defaultOptions.opacity,
503
- align: defaultOptions.align,
504
- range: defaultOptions.range
505
- });
488
+ // Tokenize
489
+ const tokens = defaultOptions.wordWrap ? text.split(" ") : text.split("");
506
490
 
507
- // Move to the next line
508
- this.nextLine(defaultOptions.padding);
509
- this.getCurrentPage().moveTo(defaultOptions.range.left, this.getCurrentPage().getY());
510
- currentLine = "";
511
- currentWidth = 0;
512
- }
491
+ let currentLine = "";
492
+ let currentWidth = 0;
513
493
 
514
- if(defaultOptions.wordWrap){
515
- currentLine += string + " ";
516
- }else{
517
- currentLine += string;
494
+ tokens.forEach((tok, i) => {
495
+ // Build what we would append for this token on this line
496
+ const needsSpace = defaultOptions.wordWrap && currentLine.length > 0;
497
+ const piece = needsSpace ? (" " + tok) : tok;
498
+
499
+ // Measure exactly what we plan to add
500
+ const pieceWidth = pdf.getCurrentFont().widthOfTextAtSize(piece, defaultOptions.size);
501
+
502
+ // If this piece would overflow, draw current line and move down
503
+ if (currentLine && (currentWidth + pieceWidth > maxWidth)) {
504
+ pdf.drawText(currentLine, {
505
+ size: defaultOptions.size,
506
+ color: defaultOptions.color,
507
+ opacity: defaultOptions.opacity,
508
+ align: defaultOptions.align,
509
+ range: defaultOptions.range
510
+ });
511
+ pdf.nextLine(defaultOptions.padding);
512
+ pdf.getCurrentPage().moveTo(defaultOptions.range.left, pdf.getCurrentPage().getY());
513
+ currentLine = tok; // start new line with the token (no leading space)
514
+ currentWidth = pdf.getCurrentFont().widthOfTextAtSize(tok, defaultOptions.size);
515
+ } else {
516
+ // Safe to add to this line
517
+ currentLine += piece;
518
+ currentWidth += pieceWidth;
518
519
  }
519
- currentWidth += wordWidth;
520
520
 
521
- // If it's the last word, draw the remaining line
522
- if (i === text.length - 1) {
523
- this.drawText(currentLine.trim(), {
524
- size: defaultOptions.size,
525
- color: defaultOptions.color,
526
- opacity: defaultOptions.opacity,
527
- align: defaultOptions.align,
528
- range: defaultOptions.range
529
- });
521
+ // Last token: flush
522
+ if (i === tokens.length - 1 && currentLine) {
523
+ pdf.drawText(currentLine, {
524
+ size: defaultOptions.size,
525
+ color: defaultOptions.color,
526
+ opacity: defaultOptions.opacity,
527
+ align: defaultOptions.align,
528
+ range: defaultOptions.range
529
+ });
530
530
  }
531
531
  });
532
532
  }