pdf-lite 1.7.3-alpha.1 → 1.7.3

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.
@@ -3,9 +3,6 @@ import { PdfAppearanceStream } from './pdf-appearance-stream.js';
3
3
  import type { PdfDictionary } from '../../core/objects/pdf-dictionary.js';
4
4
  import type { PdfFont } from '../../fonts/pdf-font.js';
5
5
  import { PdfFormFieldFlags } from '../fields/pdf-form-field-flags.js';
6
- /**
7
- * Appearance stream for choice fields (dropdowns, list boxes).
8
- */
9
6
  export declare class PdfChoiceAppearanceStream extends PdfAppearanceStream {
10
7
  constructor(ctx: {
11
8
  rect: [number, number, number, number];
@@ -18,5 +15,6 @@ export declare class PdfChoiceAppearanceStream extends PdfAppearanceStream {
18
15
  reverseEncodingMap?: Map<string, number>;
19
16
  displayOptions?: string[];
20
17
  selectedIndex?: number;
18
+ quadding?: number;
21
19
  });
22
20
  }
@@ -4,6 +4,14 @@ import { PdfFormFieldFlags } from '../fields/pdf-form-field-flags.js';
4
4
  /**
5
5
  * Appearance stream for choice fields (dropdowns, list boxes).
6
6
  */
7
+ /** Compute the X offset for a line of text given the quadding value. */
8
+ function calcTextX(quadding, padding, availableWidth, textWidth) {
9
+ if (quadding === 2)
10
+ return padding + Math.max(availableWidth - textWidth, 0);
11
+ if (quadding === 1)
12
+ return padding + Math.max((availableWidth - textWidth) / 2, 0);
13
+ return padding;
14
+ }
7
15
  export class PdfChoiceAppearanceStream extends PdfAppearanceStream {
8
16
  constructor(ctx) {
9
17
  const [x1, y1, x2, y2] = ctx.rect;
@@ -17,10 +25,14 @@ export class PdfChoiceAppearanceStream extends PdfAppearanceStream {
17
25
  const isUnicode = ctx.isUnicode ?? false;
18
26
  const reverseEncodingMap = ctx.reverseEncodingMap;
19
27
  const padding = 2;
28
+ const availableWidth = width - 2 * padding;
20
29
  const isCombo = new PdfFormFieldFlags(ctx.flags).combo;
30
+ const quadding = ctx.quadding ?? 0;
21
31
  const g = new PdfGraphics({ resolvedFonts: ctx.resolvedFonts });
22
32
  g.beginMarkedContent();
23
33
  g.save();
34
+ // Set DA early so measureTextWidth works for alignment calculations
35
+ g.setDefaultAppearance(ctx.da);
24
36
  if (!isCombo && ctx.displayOptions && ctx.displayOptions.length > 0) {
25
37
  // Listbox: render all items, highlight the selected one
26
38
  const lineHeight = ctx.da.fontSize + 4;
@@ -39,9 +51,10 @@ export class PdfChoiceAppearanceStream extends PdfAppearanceStream {
39
51
  g.restore();
40
52
  }
41
53
  const textY = itemY + lineHeight * 0.25;
54
+ const textX = calcTextX(quadding, padding, availableWidth, g.measureTextWidth(ctx.displayOptions[i]));
42
55
  g.beginText();
43
56
  g.setDefaultAppearance(ctx.da);
44
- g.moveTo(padding, textY);
57
+ g.moveTo(textX, textY);
45
58
  g.showText(ctx.displayOptions[i], isUnicode, reverseEncodingMap);
46
59
  g.endText();
47
60
  }
@@ -49,9 +62,10 @@ export class PdfChoiceAppearanceStream extends PdfAppearanceStream {
49
62
  else {
50
63
  // Combo (dropdown) or no options: show selected value only
51
64
  const textY = (height - ctx.da.fontSize) / 2 + ctx.da.fontSize * 0.2;
65
+ const textX = calcTextX(quadding, padding, availableWidth, g.measureTextWidth(ctx.value));
52
66
  g.beginText();
53
67
  g.setDefaultAppearance(ctx.da);
54
- g.moveTo(padding, textY);
68
+ g.moveTo(textX, textY);
55
69
  g.showText(ctx.value, isUnicode, reverseEncodingMap);
56
70
  g.endText();
57
71
  if (isCombo) {
@@ -21,5 +21,6 @@ export declare class PdfTextAppearanceStream extends PdfAppearanceStream {
21
21
  reverseEncodingMap?: Map<string, number>;
22
22
  markdown?: string;
23
23
  fontVariantNames?: FontVariantNames;
24
+ quadding?: number;
24
25
  });
25
26
  }
@@ -2,6 +2,19 @@ import { PdfDefaultAppearance } from '../fields/pdf-default-appearance.js';
2
2
  import { PdfAppearanceStream } from './pdf-appearance-stream.js';
3
3
  import { PdfGraphics } from './pdf-graphics.js';
4
4
  const DEFAULT_FONT_SIZE = 12;
5
+ /** Compute the X offset for a line of text given the quadding value. */
6
+ function calcTextX(quadding, padding, availableWidth, textWidth) {
7
+ if (quadding === 2) {
8
+ // Right-aligned
9
+ return padding + Math.max(availableWidth - textWidth, 0);
10
+ }
11
+ if (quadding === 1) {
12
+ // Center-aligned
13
+ return padding + Math.max((availableWidth - textWidth) / 2, 0);
14
+ }
15
+ // Left-aligned (default)
16
+ return padding;
17
+ }
5
18
  /**
6
19
  * Appearance stream for text fields (single-line, multiline, comb).
7
20
  * Enhanced with word wrapping and automatic font scaling.
@@ -18,6 +31,7 @@ export class PdfTextAppearanceStream extends PdfAppearanceStream {
18
31
  const availableWidth = width - 2 * padding;
19
32
  const availableHeight = height - 2 * padding;
20
33
  const autoSize = ctx.da.fontSize <= 0;
34
+ const quadding = ctx.quadding ?? 0;
21
35
  // Create graphics with font context for text measurement
22
36
  const g = new PdfGraphics({
23
37
  resolvedFonts: ctx.resolvedFonts,
@@ -108,11 +122,18 @@ export class PdfTextAppearanceStream extends PdfAppearanceStream {
108
122
  }
109
123
  else {
110
124
  g.beginText();
111
- g.moveTo(padding, startY);
125
+ let prevLineX = 0;
112
126
  for (let i = 0; i < lines.length; i++) {
113
- if (i > 0)
114
- g.moveTo(0, -renderLineHeight);
115
- g.showText(lines[i].replace(/\r/g, ''), isUnicode, reverseEncodingMap);
127
+ const lineText = lines[i].replace(/\r/g, '');
128
+ const lineX = calcTextX(quadding, padding, availableWidth, g.measureTextWidth(lineText));
129
+ if (i === 0) {
130
+ g.moveTo(lineX, startY);
131
+ }
132
+ else {
133
+ g.moveTo(lineX - prevLineX, -renderLineHeight);
134
+ }
135
+ prevLineX = lineX;
136
+ g.showText(lineText, isUnicode, reverseEncodingMap);
116
137
  }
117
138
  g.endText();
118
139
  }
@@ -126,12 +147,14 @@ export class PdfTextAppearanceStream extends PdfAppearanceStream {
126
147
  }
127
148
  }
128
149
  const textY = (height - finalFontSize) / 2 + finalFontSize * 0.2;
150
+ const textWidth = g.measureTextWidth(value);
151
+ const textX = calcTextX(quadding, padding, availableWidth, textWidth);
129
152
  if (ctx.markdown) {
130
- g.showMarkdown(ctx.markdown, isUnicode, reverseEncodingMap, padding, textY, finalFontSize);
153
+ g.showMarkdown(ctx.markdown, isUnicode, reverseEncodingMap, textX, textY, finalFontSize);
131
154
  }
132
155
  else {
133
156
  g.beginText();
134
- g.moveTo(padding, textY);
157
+ g.moveTo(textX, textY);
135
158
  g.showText(value, isUnicode, reverseEncodingMap);
136
159
  g.endText();
137
160
  }
@@ -101,6 +101,7 @@ export class PdfChoiceFormField extends PdfFormField {
101
101
  reverseEncodingMap,
102
102
  displayOptions: this.options.map((opt) => opt.label),
103
103
  selectedIndex: this.selectedIndex,
104
+ quadding: this.quadding,
104
105
  });
105
106
  if (options?.makeReadOnly) {
106
107
  this.readOnly = true;
@@ -600,6 +600,7 @@ export class PdfFormField extends PdfWidgetAnnotation {
600
600
  }
601
601
  set quadding(q) {
602
602
  this.content.set('Q', new PdfNumber(q));
603
+ this.updateAppearance();
603
604
  }
604
605
  get defaultAppearance() {
605
606
  return (this.content.get('DA')?.as(PdfString)?.value ??
@@ -54,6 +54,7 @@ export class PdfTextFormField extends PdfFormField {
54
54
  reverseEncodingMap,
55
55
  markdown: this.markdownValue,
56
56
  fontVariantNames: variantNames,
57
+ quadding: this.quadding,
57
58
  });
58
59
  if (options?.makeReadOnly) {
59
60
  this.readOnly = true;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pdf-lite",
3
- "version": "1.7.3-alpha.1",
3
+ "version": "1.7.3",
4
4
  "main": "dist/index.js",
5
5
  "type": "module",
6
6
  "exports": {