pdf-oxide 0.3.39 → 0.3.41

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.
@@ -251,6 +251,12 @@ export declare class PageBuilder {
251
251
  barcode1d(barcodeType: number, data: string, x: number, y: number, w: number, h: number): this;
252
252
  /** Place a QR-code image on the page (square: `size × size` pt). */
253
253
  barcodeQr(data: string, x: number, y: number, size: number): this;
254
+ /**
255
+ * Embed a JPEG/PNG image at (x, y, w, h) in PDF points.
256
+ * No alt text or /Artifact wrapper. Use `imageWithAlt` or `imageArtifact`
257
+ * for PDF/UA-1 accessibility requirements.
258
+ */
259
+ image(bytes: Buffer | Uint8Array, x: number, y: number, w: number, h: number): this;
254
260
  /**
255
261
  * Embed an image with an accessibility alt text (PDF/UA-1 §Figure).
256
262
  * `bytes` must contain raw JPEG/PNG/WebP image data.
@@ -282,6 +288,23 @@ export declare class PageBuilder {
282
288
  width?: number;
283
289
  color?: [number, number, number];
284
290
  }): this;
291
+ /**
292
+ * Draw a dashed rectangle outline. `dash` is the on/off lengths in PDF
293
+ * points (e.g. `[3, 2]` → 3 pt on, 2 pt off). `phase` offsets the dash
294
+ * start within the pattern.
295
+ */
296
+ strokeRectDashed(x: number, y: number, w: number, h: number, dash: number[], phase?: number, style?: {
297
+ width?: number;
298
+ color?: [number, number, number];
299
+ }): this;
300
+ /**
301
+ * Draw a dashed straight line. `dash` / `phase` semantics are the same as
302
+ * {@link strokeRectDashed}.
303
+ */
304
+ strokeLineDashed(x1: number, y1: number, x2: number, y2: number, dash: number[], phase?: number, style?: {
305
+ width?: number;
306
+ color?: [number, number, number];
307
+ }): this;
285
308
  /**
286
309
  * Place wrapped text inside the rectangle (x, y, w, h) with the
287
310
  * given horizontal alignment. Uses the current font + size. Text
@@ -328,6 +351,14 @@ export declare class PageBuilder {
328
351
  _streamingTablePushRow(cells: Array<string | null>): void;
329
352
  /** @internal — push one row with per-cell rowspan values. */
330
353
  _streamingTablePushRowV2(cells: Array<[string | null, number]>): void;
354
+ /** @internal — set the batch size for the open streaming table. */
355
+ _streamingTableSetBatchSize(batchSize: number): void;
356
+ /** @internal — return pending row count from native layer. */
357
+ _streamingTablePendingRowCount(): number;
358
+ /** @internal — return batch count from native layer. */
359
+ _streamingTableBatchCount(): number;
360
+ /** @internal — flush (mark batch boundary) in native layer. */
361
+ _streamingTableFlush(): void;
331
362
  /** @internal — close the open streaming table. */
332
363
  _streamingTableFinish(): void;
333
364
  /** @internal — track the last font size for JS-side `measure()`. */
@@ -523,6 +523,15 @@ export class PageBuilder {
523
523
  native.pageBuilderBarcodeQr(this.h(), data, x, y, size);
524
524
  return this;
525
525
  }
526
+ /**
527
+ * Embed a JPEG/PNG image at (x, y, w, h) in PDF points.
528
+ * No alt text or /Artifact wrapper. Use `imageWithAlt` or `imageArtifact`
529
+ * for PDF/UA-1 accessibility requirements.
530
+ */
531
+ image(bytes, x, y, w, h) {
532
+ native.pageBuilderImage(this.h(), bytes, x, y, w, h);
533
+ return this;
534
+ }
526
535
  /**
527
536
  * Embed an image with an accessibility alt text (PDF/UA-1 §Figure).
528
537
  * `bytes` must contain raw JPEG/PNG/WebP image data.
@@ -575,6 +584,27 @@ export class PageBuilder {
575
584
  native.pageBuilderStrokeLine(this.h(), x1, y1, x2, y2, width, r, g, b);
576
585
  return this;
577
586
  }
587
+ /**
588
+ * Draw a dashed rectangle outline. `dash` is the on/off lengths in PDF
589
+ * points (e.g. `[3, 2]` → 3 pt on, 2 pt off). `phase` offsets the dash
590
+ * start within the pattern.
591
+ */
592
+ strokeRectDashed(x, y, w, h, dash, phase = 0, style) {
593
+ const width = style?.width ?? 1;
594
+ const [r, g, b] = style?.color ?? [0, 0, 0];
595
+ native.pageBuilderStrokeRectDashed(this.h(), x, y, w, h, width, r, g, b, dash, phase);
596
+ return this;
597
+ }
598
+ /**
599
+ * Draw a dashed straight line. `dash` / `phase` semantics are the same as
600
+ * {@link strokeRectDashed}.
601
+ */
602
+ strokeLineDashed(x1, y1, x2, y2, dash, phase = 0, style) {
603
+ const width = style?.width ?? 1;
604
+ const [r, g, b] = style?.color ?? [0, 0, 0];
605
+ native.pageBuilderStrokeLineDashed(this.h(), x1, y1, x2, y2, width, r, g, b, dash, phase);
606
+ return this;
607
+ }
578
608
  /**
579
609
  * Place wrapped text inside the rectangle (x, y, w, h) with the
580
610
  * given horizontal alignment. Uses the current font + size. Text
@@ -681,6 +711,22 @@ export class PageBuilder {
681
711
  _streamingTablePushRowV2(cells) {
682
712
  native.pageBuilderStreamingTablePushRowV2(this.h(), cells);
683
713
  }
714
+ /** @internal — set the batch size for the open streaming table. */
715
+ _streamingTableSetBatchSize(batchSize) {
716
+ native.pageBuilderStreamingTableSetBatchSize(this.h(), batchSize);
717
+ }
718
+ /** @internal — return pending row count from native layer. */
719
+ _streamingTablePendingRowCount() {
720
+ return native.pageBuilderStreamingTablePendingRowCount(this.h());
721
+ }
722
+ /** @internal — return batch count from native layer. */
723
+ _streamingTableBatchCount() {
724
+ return native.pageBuilderStreamingTableBatchCount(this.h());
725
+ }
726
+ /** @internal — flush (mark batch boundary) in native layer. */
727
+ _streamingTableFlush() {
728
+ native.pageBuilderStreamingTableFlush(this.h());
729
+ }
684
730
  /** @internal — close the open streaming table. */
685
731
  _streamingTableFinish() {
686
732
  native.pageBuilderStreamingTableFinish(this.h());
@@ -26,8 +26,23 @@ export declare class StreamingTable {
26
26
  private _columns;
27
27
  private _opened;
28
28
  private _finished;
29
+ private _rowCount;
29
30
  /** @internal — constructed via `PageBuilder.streamingTable(...)`. */
30
31
  constructor(page: PageBuilder, config: StreamingTableConfig);
32
+ /**
33
+ * Number of rows pushed since the last batch boundary.
34
+ * Backed by the Rust FFI layer.
35
+ */
36
+ get pendingRowCount(): number;
37
+ /** Number of complete batches recorded by the native layer so far. */
38
+ get batchCount(): number;
39
+ /**
40
+ * Explicitly mark a batch boundary in the native layer.
41
+ * Also triggered automatically when the configured batch size is reached.
42
+ */
43
+ flush(): this;
44
+ /** Total rows pushed so far (monotonically increasing). */
45
+ get rowCount(): number;
31
46
  /** Push a single row (all rowspan=1). Throws if `cells.length !== columns.length`. */
32
47
  pushRow(cells: Array<string | null | undefined>): this;
33
48
  /**
@@ -24,6 +24,7 @@ export class StreamingTable {
24
24
  constructor(page, config) {
25
25
  this._opened = false;
26
26
  this._finished = false;
27
+ this._rowCount = 0;
27
28
  if (!config || !Array.isArray(config.columns) || config.columns.length === 0) {
28
29
  throw new Error('StreamingTable requires at least one column');
29
30
  }
@@ -36,6 +37,33 @@ export class StreamingTable {
36
37
  const maxRowspan = config.maxRowspan != null && config.maxRowspan >= 2 ? config.maxRowspan : 1;
37
38
  this._page._streamingTableBeginV2(headers, widths, aligns, repeat, config.mode, maxRowspan);
38
39
  this._opened = true;
40
+ const batchSize = config.batchSize != null && config.batchSize > 0 ? config.batchSize : 256;
41
+ this._page._streamingTableSetBatchSize(batchSize);
42
+ }
43
+ /**
44
+ * Number of rows pushed since the last batch boundary.
45
+ * Backed by the Rust FFI layer.
46
+ */
47
+ get pendingRowCount() {
48
+ return this._page._streamingTablePendingRowCount();
49
+ }
50
+ /** Number of complete batches recorded by the native layer so far. */
51
+ get batchCount() {
52
+ return this._page._streamingTableBatchCount();
53
+ }
54
+ /**
55
+ * Explicitly mark a batch boundary in the native layer.
56
+ * Also triggered automatically when the configured batch size is reached.
57
+ */
58
+ flush() {
59
+ if (this._finished)
60
+ throw new Error('StreamingTable already finished');
61
+ this._page._streamingTableFlush();
62
+ return this;
63
+ }
64
+ /** Total rows pushed so far (monotonically increasing). */
65
+ get rowCount() {
66
+ return this._rowCount;
39
67
  }
40
68
  /** Push a single row (all rowspan=1). Throws if `cells.length !== columns.length`. */
41
69
  pushRow(cells) {
@@ -46,6 +74,7 @@ export class StreamingTable {
46
74
  throw new Error(`row width ${cells.length} does not match column count ${this._columns.length}`);
47
75
  }
48
76
  this._page._streamingTablePushRow(cells.map((c) => (c == null ? null : String(c))));
77
+ this._rowCount++;
49
78
  return this;
50
79
  }
51
80
  /**
@@ -68,6 +97,7 @@ export class StreamingTable {
68
97
  return [c.text, c.rowspan];
69
98
  });
70
99
  this._page._streamingTablePushRowV2(normalized);
100
+ this._rowCount++;
71
101
  return this;
72
102
  }
73
103
  /**
@@ -112,6 +112,8 @@ export declare class DocumentEditor {
112
112
  save(path: string): void;
113
113
  /** Save with AES-256 encryption (user + owner passwords). */
114
114
  saveEncrypted(path: string, userPassword: string, ownerPassword: string): void;
115
+ /** Extract specific pages (by 0-based index) into a new PDF returned as a Buffer. */
116
+ extractPagesToBytes(pageIndices: number[]): Buffer;
115
117
  /** Save the document to an in-memory Buffer. */
116
118
  saveToBytes(): Buffer;
117
119
  /** Save to an in-memory Buffer with explicit compression / GC / linearize flags. */
@@ -289,6 +289,11 @@ export class DocumentEditor {
289
289
  this._throwIfClosed();
290
290
  native.editorSaveEncrypted(this._handle, path, userPassword, ownerPassword);
291
291
  }
292
+ /** Extract specific pages (by 0-based index) into a new PDF returned as a Buffer. */
293
+ extractPagesToBytes(pageIndices) {
294
+ this._throwIfClosed();
295
+ return native.editorExtractPagesToBytes(this._handle, pageIndices);
296
+ }
292
297
  /** Save the document to an in-memory Buffer. */
293
298
  saveToBytes() {
294
299
  this._throwIfClosed();
package/lib/index.d.ts CHANGED
@@ -81,6 +81,26 @@ declare class PdfDocumentImpl {
81
81
  estimateRenderTime(pageIndex: number, dpi?: number): number;
82
82
  page(index: number): Page;
83
83
  [Symbol.iterator](): Iterator<Page>;
84
+ /**
85
+ * Validate PDF/A conformance at a given level.
86
+ * @param level - "1a"|"1b"|"2a"|"2b"|"2u"|"3a"|"3b"|"3u" (default "2b")
87
+ */
88
+ validatePdfA(level?: '1a' | '1b' | '2a' | '2b' | '2u' | '3a' | '3b' | '3u'): {
89
+ compliant: boolean;
90
+ errors: string[];
91
+ warnings: string[];
92
+ };
93
+ /**
94
+ * Convert document to PDF/A conformance in-place.
95
+ * @param level - "1b"|"2b"|"2u"|"3b" etc. (default "2b")
96
+ * @returns true if the document is fully PDF/A-compliant after conversion (false if errors remain, e.g. fonts not embeddable without the rendering feature)
97
+ */
98
+ convertToPdfA(level?: '1a' | '1b' | '2a' | '2b' | '2u' | '3a' | '3b' | '3u'): boolean;
99
+ /**
100
+ * Return the current document bytes (including any in-place modifications
101
+ * made by convertToPdfA).
102
+ */
103
+ toBuffer(): Buffer;
84
104
  close(): void;
85
105
  [Symbol.dispose](): void;
86
106
  }
@@ -107,6 +127,8 @@ declare class Page {
107
127
  search(query: string, caseSensitive?: boolean): any;
108
128
  toString(): string;
109
129
  }
130
+ declare function generateBarcodeSvg(data: string, format?: number, sizePx?: number): string;
131
+ declare function generateQrCodeSvg(data: string, errorCorrection?: number, sizePx?: number): string;
110
132
  declare const getVersion: any;
111
133
  declare const getPdfOxideVersion: any;
112
134
  declare const PdfDocument: any;
@@ -123,4 +145,4 @@ declare const TextSearcher: any;
123
145
  export { Timestamp, TimestampHashAlgorithm } from './timestamp.js';
124
146
  export { TsaClient, type TsaClientOptions } from './tsa-client.js';
125
147
  export type { BatchDocument, BatchOptions, BatchProgress, BatchResult, BatchStatistics, Column, SpanCell, StreamingTableConfig, Table, TableMode, TableSpec, WorkerResult, WorkerTask, };
126
- export { AccessibilityException, AccessibilityManager, Align, AnnotationBuilder, AnnotationManager, AnnotationProperties, BarcodeErrorCorrection, BarcodeFormat, BarcodeManager, BatchManager, CacheManager, CertificateLoadFailed, Color, ComplianceException, ComplianceIssueType, ComplianceManager, ContentType, ConversionOptions, ConversionOptionsBuilder, createExtractionStream, createMetadataStream, createSearchStream, DigestAlgorithm, DocumentBuilder, DocumentEditor, EditingManager, EmbeddedFont, EncryptionException, EnterpriseManager, ErrorCategory, ErrorSeverity, ExtractionManager, ExtractionStream, FieldVisibility, FontProperties, FormFieldManager, FormFieldType, getPdfOxideVersion, getVersion, HybridMLManager, ImageFormat, ImageProperties, InvalidStateException, IoException, IssueSeverity, LayerManager, MetadataBuilder, MetadataManager, MetadataStream, mapFfiErrorCode, OCRDetectionMode, OCRLanguage, OCRManager, OcrException, OcrManager, OptimizationException, OptimizationManager, OutlineManager, Page, PageBuilder, PageComplexity, PageSize, ParseException, Pdf, PdfALevel, PdfBuilder, PdfDocument, PdfError, PdfException, PdfUALevel, PdfXLevel, Point, Rect, RedactionException, RenderingException, RenderingManager, ResultAccessorsManager, SearchException, SearchManager, SearchOptions, SearchOptionsBuilder, SearchResult, SearchResultProperties, SearchStream, SecurityManager, SignatureAlgorithm, SignatureException, SignatureManager, SigningFailed, StreamingTable, TextSearcher, ThumbnailManager, ThumbnailSize, UnknownError, UnsupportedFeatureException, ValidationException, WorkerPool, workerPool, wrapAsyncMethod, wrapError, wrapMethod, XfaFieldType, XfaFormType, XfaManager, };
148
+ export { AccessibilityException, AccessibilityManager, Align, AnnotationBuilder, AnnotationManager, AnnotationProperties, BarcodeErrorCorrection, BarcodeFormat, BarcodeManager, BatchManager, CacheManager, CertificateLoadFailed, Color, ComplianceException, ComplianceIssueType, ComplianceManager, ContentType, ConversionOptions, ConversionOptionsBuilder, createExtractionStream, createMetadataStream, createSearchStream, DigestAlgorithm, DocumentBuilder, DocumentEditor, EditingManager, EmbeddedFont, EncryptionException, EnterpriseManager, ErrorCategory, ErrorSeverity, ExtractionManager, ExtractionStream, FieldVisibility, FontProperties, FormFieldManager, FormFieldType, generateBarcodeSvg, generateQrCodeSvg, getPdfOxideVersion, getVersion, HybridMLManager, ImageFormat, ImageProperties, InvalidStateException, IoException, IssueSeverity, LayerManager, MetadataBuilder, MetadataManager, MetadataStream, mapFfiErrorCode, OCRDetectionMode, OCRLanguage, OCRManager, OcrException, OcrManager, OptimizationException, OptimizationManager, OutlineManager, Page, PageBuilder, PageComplexity, PageSize, ParseException, Pdf, PdfALevel, PdfBuilder, PdfDocument, PdfError, PdfException, PdfUALevel, PdfXLevel, Point, Rect, RedactionException, RenderingException, RenderingManager, ResultAccessorsManager, SearchException, SearchManager, SearchOptions, SearchOptionsBuilder, SearchResult, SearchResultProperties, SearchStream, SecurityManager, SignatureAlgorithm, SignatureException, SignatureManager, SigningFailed, StreamingTable, TextSearcher, ThumbnailManager, ThumbnailSize, UnknownError, UnsupportedFeatureException, ValidationException, WorkerPool, workerPool, wrapAsyncMethod, wrapError, wrapMethod, XfaFieldType, XfaFormType, XfaManager, };
package/lib/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ // SPDX-License-Identifier: MIT OR Apache-2.0
1
2
  // PDF Oxide Node.js bindings - Native module loader
2
3
  import { createRequire } from 'node:module';
3
4
  import { dirname } from 'node:path';
@@ -333,6 +334,57 @@ class PdfDocumentImpl {
333
334
  },
334
335
  };
335
336
  }
337
+ /**
338
+ * Validate PDF/A conformance at a given level.
339
+ * @param level - "1a"|"1b"|"2a"|"2b"|"2u"|"3a"|"3b"|"3u" (default "2b")
340
+ */
341
+ validatePdfA(level = '2b') {
342
+ this.ensureOpen();
343
+ const levelMap = {
344
+ '1b': 0,
345
+ '1a': 1,
346
+ '2b': 2,
347
+ '2a': 3,
348
+ '2u': 4,
349
+ '3b': 5,
350
+ '3a': 6,
351
+ '3u': 7,
352
+ };
353
+ const levelInt = levelMap[level];
354
+ if (levelInt === undefined)
355
+ throw new RangeError(`Unknown PDF/A level: "${level}"`);
356
+ return native.validatePdfALevel(this._handle, levelInt);
357
+ }
358
+ /**
359
+ * Convert document to PDF/A conformance in-place.
360
+ * @param level - "1b"|"2b"|"2u"|"3b" etc. (default "2b")
361
+ * @returns true if the document is fully PDF/A-compliant after conversion (false if errors remain, e.g. fonts not embeddable without the rendering feature)
362
+ */
363
+ convertToPdfA(level = '2b') {
364
+ this.ensureOpen();
365
+ const levelMap = {
366
+ '1b': 0,
367
+ '1a': 1,
368
+ '2b': 2,
369
+ '2a': 3,
370
+ '2u': 4,
371
+ '3b': 5,
372
+ '3a': 6,
373
+ '3u': 7,
374
+ };
375
+ const levelInt = levelMap[level];
376
+ if (levelInt === undefined)
377
+ throw new RangeError(`Unknown PDF/A level: "${level}"`);
378
+ return native.convertToPdfA(this._handle, levelInt);
379
+ }
380
+ /**
381
+ * Return the current document bytes (including any in-place modifications
382
+ * made by convertToPdfA).
383
+ */
384
+ toBuffer() {
385
+ this.ensureOpen();
386
+ return native.documentGetSourceBytes(this._handle);
387
+ }
336
388
  close() {
337
389
  if (!this._closed && this._handle) {
338
390
  native.closeDocument(this._handle);
@@ -464,6 +516,28 @@ class PdfImpl {
464
516
  this.close();
465
517
  }
466
518
  }
519
+ // Generate a 1D barcode as a vector SVG string.
520
+ // format: 0=Code128, 1=Code39, 2=EAN13, 3=EAN8, 4=UPCA, 5=ITF, 6=Code93, 7=Codabar.
521
+ function generateBarcodeSvg(data, format = 0, sizePx = 300) {
522
+ const handle = native.generateBarcode(format, data);
523
+ try {
524
+ return native.barcodeGetSVG(handle, sizePx);
525
+ }
526
+ finally {
527
+ native.freeBarcode(handle);
528
+ }
529
+ }
530
+ // Generate a QR code as a vector SVG string.
531
+ // errorCorrection: 0=Low, 1=Medium, 2=Quartile, 3=High.
532
+ function generateQrCodeSvg(data, errorCorrection = 1, sizePx = 300) {
533
+ const handle = native.generateQRCode(data, errorCorrection);
534
+ try {
535
+ return native.barcodeGetSVG(handle, sizePx);
536
+ }
537
+ finally {
538
+ native.freeBarcode(handle);
539
+ }
540
+ }
467
541
  // Export as ES module
468
542
  const getVersion = native.getVersion;
469
543
  const getPdfOxideVersion = native.getPdfOxideVersion;
@@ -492,7 +566,7 @@ DocumentBuilder,
492
566
  // Editor mutation API
493
567
  DocumentEditor, EditingManager, EmbeddedFont, EncryptionException, EnterpriseManager,
494
568
  // Error utilities
495
- ErrorCategory, ErrorSeverity, ExtractionManager, ExtractionStream, FieldVisibility, FontProperties, FormFieldManager, FormFieldType, getPdfOxideVersion,
569
+ ErrorCategory, ErrorSeverity, ExtractionManager, ExtractionStream, FieldVisibility, FontProperties, FormFieldManager, FormFieldType, generateBarcodeSvg, generateQrCodeSvg, getPdfOxideVersion,
496
570
  // Version info
497
571
  getVersion, HybridMLManager, ImageFormat, ImageProperties, InvalidStateException, IoException, IssueSeverity, LayerManager, MetadataBuilder, MetadataManager, MetadataStream, mapFfiErrorCode, OCRDetectionMode, OCRLanguage, OCRManager, OcrException,
498
572
  // Managers (Phase 4+, consolidated in Phase 9)
@@ -49,6 +49,7 @@ export interface BarcodeGenerationConfig {
49
49
  format?: BarcodeFormat;
50
50
  width?: number;
51
51
  height?: number;
52
+ sizePx?: number;
52
53
  errorCorrection?: BarcodeErrorCorrection;
53
54
  margin?: number;
54
55
  }
@@ -68,6 +69,8 @@ export declare class BarcodeManager extends EventEmitter {
68
69
  generateQrCode(data: string, errorCorrection?: QrErrorCorrection, sizePx?: number): Promise<Buffer>;
69
70
  barcodeToPng(barcodeData: Buffer, sizePx?: number): Promise<Buffer>;
70
71
  barcodeToSvg(barcodeData: Buffer, sizePx?: number): Promise<string>;
72
+ generateSvg(data: string, config?: BarcodeGenerationConfig): Promise<string>;
73
+ generateQrSvg(data: string, errorCorrection?: QrErrorCorrection, sizePx?: number): Promise<string>;
71
74
  addBarcodeToPage(pageIndex: number, barcodeData: Buffer, x: number, y: number, width: number, height: number): Promise<boolean>;
72
75
  detectBarcodeFormat(barcodeData: Buffer): BarcodeFormat;
73
76
  decodeBarcodeData(barcodeData: Buffer): string;
@@ -187,9 +187,36 @@ export class BarcodeManager extends EventEmitter {
187
187
  return barcodeData;
188
188
  }
189
189
  async barcodeToSvg(barcodeData, sizePx = 256) {
190
+ // Legacy: wraps existing PNG bytes in an SVG <image> element.
191
+ // For real vector SVG use generateBarcodeSvg() / generateQrCodeSvg() from the top-level API.
190
192
  const encoded = barcodeData.toString('base64');
191
193
  return `<svg xmlns="http://www.w3.org/2000/svg"><image href="data:image/png;base64,${encoded}"/></svg>`;
192
194
  }
195
+ async generateSvg(data, config) {
196
+ const format = config?.format ?? BarcodeFormat.CODE128;
197
+ if (this.native?.generateBarcode && this.native?.barcodeGetSVG && this.native?.freeBarcode) {
198
+ const handle = this.native.generateBarcode(format, data);
199
+ try {
200
+ return this.native.barcodeGetSVG(handle, config?.sizePx ?? 300);
201
+ }
202
+ finally {
203
+ this.native.freeBarcode(handle);
204
+ }
205
+ }
206
+ return '';
207
+ }
208
+ async generateQrSvg(data, errorCorrection = QrErrorCorrection.M, sizePx = 300) {
209
+ if (this.native?.generateQRCode && this.native?.barcodeGetSVG && this.native?.freeBarcode) {
210
+ const handle = this.native.generateQRCode(data, errorCorrection);
211
+ try {
212
+ return this.native.barcodeGetSVG(handle, sizePx);
213
+ }
214
+ finally {
215
+ this.native.freeBarcode(handle);
216
+ }
217
+ }
218
+ return '';
219
+ }
193
220
  async addBarcodeToPage(pageIndex, barcodeData, x, y, width, height) {
194
221
  try {
195
222
  if (!this.document)
@@ -173,6 +173,11 @@ export interface StreamingTableConfig {
173
173
  * Set to ≥2 to allow `pushRowSpan` cells to span multiple rows.
174
174
  */
175
175
  maxRowspan?: number;
176
+ /**
177
+ * Maximum rows to buffer before an automatic batch flush in the native
178
+ * layer. 0 or unset defaults to 256.
179
+ */
180
+ batchSize?: number;
176
181
  }
177
182
  /**
178
183
  * A single cell value for `StreamingTable.pushRowSpan`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pdf-oxide",
3
- "version": "0.3.39",
3
+ "version": "0.3.41",
4
4
  "type": "module",
5
5
  "description": "High-performance PDF parsing and text extraction library — prebuilt native bindings, no build toolchain required",
6
6
  "main": "lib/index.js",
Binary file
Binary file
Binary file