@lexmata/micropdf 0.4.0

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.
Files changed (170) hide show
  1. package/LICENSE +191 -0
  2. package/README.md +985 -0
  3. package/binding.gyp +73 -0
  4. package/dist/annot.d.ts +458 -0
  5. package/dist/annot.d.ts.map +1 -0
  6. package/dist/annot.js +697 -0
  7. package/dist/annot.js.map +1 -0
  8. package/dist/archive.d.ts +128 -0
  9. package/dist/archive.d.ts.map +1 -0
  10. package/dist/archive.js +268 -0
  11. package/dist/archive.js.map +1 -0
  12. package/dist/buffer.d.ts +572 -0
  13. package/dist/buffer.d.ts.map +1 -0
  14. package/dist/buffer.js +971 -0
  15. package/dist/buffer.js.map +1 -0
  16. package/dist/colorspace.d.ts +287 -0
  17. package/dist/colorspace.d.ts.map +1 -0
  18. package/dist/colorspace.js +542 -0
  19. package/dist/colorspace.js.map +1 -0
  20. package/dist/context.d.ts +184 -0
  21. package/dist/context.d.ts.map +1 -0
  22. package/dist/context.js +320 -0
  23. package/dist/context.js.map +1 -0
  24. package/dist/cookie.d.ts +164 -0
  25. package/dist/cookie.d.ts.map +1 -0
  26. package/dist/cookie.js +306 -0
  27. package/dist/cookie.js.map +1 -0
  28. package/dist/device.d.ts +169 -0
  29. package/dist/device.d.ts.map +1 -0
  30. package/dist/device.js +350 -0
  31. package/dist/device.js.map +1 -0
  32. package/dist/display-list.d.ts +202 -0
  33. package/dist/display-list.d.ts.map +1 -0
  34. package/dist/display-list.js +410 -0
  35. package/dist/display-list.js.map +1 -0
  36. package/dist/document.d.ts +637 -0
  37. package/dist/document.d.ts.map +1 -0
  38. package/dist/document.js +902 -0
  39. package/dist/document.js.map +1 -0
  40. package/dist/easy.d.ts +423 -0
  41. package/dist/easy.d.ts.map +1 -0
  42. package/dist/easy.js +644 -0
  43. package/dist/easy.js.map +1 -0
  44. package/dist/enhanced.d.ts +226 -0
  45. package/dist/enhanced.d.ts.map +1 -0
  46. package/dist/enhanced.js +368 -0
  47. package/dist/enhanced.js.map +1 -0
  48. package/dist/filter.d.ts +51 -0
  49. package/dist/filter.d.ts.map +1 -0
  50. package/dist/filter.js +381 -0
  51. package/dist/filter.js.map +1 -0
  52. package/dist/font.d.ts +222 -0
  53. package/dist/font.d.ts.map +1 -0
  54. package/dist/font.js +381 -0
  55. package/dist/font.js.map +1 -0
  56. package/dist/form.d.ts +214 -0
  57. package/dist/form.d.ts.map +1 -0
  58. package/dist/form.js +497 -0
  59. package/dist/form.js.map +1 -0
  60. package/dist/geometry.d.ts +469 -0
  61. package/dist/geometry.d.ts.map +1 -0
  62. package/dist/geometry.js +780 -0
  63. package/dist/geometry.js.map +1 -0
  64. package/dist/image.d.ts +172 -0
  65. package/dist/image.d.ts.map +1 -0
  66. package/dist/image.js +348 -0
  67. package/dist/image.js.map +1 -0
  68. package/dist/index.d.ts +171 -0
  69. package/dist/index.d.ts.map +1 -0
  70. package/dist/index.js +339 -0
  71. package/dist/index.js.map +1 -0
  72. package/dist/link.d.ts +168 -0
  73. package/dist/link.d.ts.map +1 -0
  74. package/dist/link.js +343 -0
  75. package/dist/link.js.map +1 -0
  76. package/dist/micropdf.d.ts +40 -0
  77. package/dist/micropdf.d.ts.map +1 -0
  78. package/dist/micropdf.js +45 -0
  79. package/dist/micropdf.js.map +1 -0
  80. package/dist/nanopdf.d.ts +40 -0
  81. package/dist/nanopdf.d.ts.map +1 -0
  82. package/dist/nanopdf.js +45 -0
  83. package/dist/nanopdf.js.map +1 -0
  84. package/dist/native.d.ts +242 -0
  85. package/dist/native.d.ts.map +1 -0
  86. package/dist/native.js +509 -0
  87. package/dist/native.js.map +1 -0
  88. package/dist/output.d.ts +166 -0
  89. package/dist/output.d.ts.map +1 -0
  90. package/dist/output.js +365 -0
  91. package/dist/output.js.map +1 -0
  92. package/dist/path.d.ts +420 -0
  93. package/dist/path.d.ts.map +1 -0
  94. package/dist/path.js +687 -0
  95. package/dist/path.js.map +1 -0
  96. package/dist/pdf/object.d.ts +489 -0
  97. package/dist/pdf/object.d.ts.map +1 -0
  98. package/dist/pdf/object.js +1045 -0
  99. package/dist/pdf/object.js.map +1 -0
  100. package/dist/pixmap.d.ts +315 -0
  101. package/dist/pixmap.d.ts.map +1 -0
  102. package/dist/pixmap.js +590 -0
  103. package/dist/pixmap.js.map +1 -0
  104. package/dist/profiler.d.ts +159 -0
  105. package/dist/profiler.d.ts.map +1 -0
  106. package/dist/profiler.js +380 -0
  107. package/dist/profiler.js.map +1 -0
  108. package/dist/render-options.d.ts +227 -0
  109. package/dist/render-options.d.ts.map +1 -0
  110. package/dist/render-options.js +130 -0
  111. package/dist/render-options.js.map +1 -0
  112. package/dist/resource-tracking.d.ts +332 -0
  113. package/dist/resource-tracking.d.ts.map +1 -0
  114. package/dist/resource-tracking.js +653 -0
  115. package/dist/resource-tracking.js.map +1 -0
  116. package/dist/simple.d.ts +276 -0
  117. package/dist/simple.d.ts.map +1 -0
  118. package/dist/simple.js +343 -0
  119. package/dist/simple.js.map +1 -0
  120. package/dist/stext.d.ts +290 -0
  121. package/dist/stext.d.ts.map +1 -0
  122. package/dist/stext.js +312 -0
  123. package/dist/stext.js.map +1 -0
  124. package/dist/stream.d.ts +174 -0
  125. package/dist/stream.d.ts.map +1 -0
  126. package/dist/stream.js +476 -0
  127. package/dist/stream.js.map +1 -0
  128. package/dist/text.d.ts +337 -0
  129. package/dist/text.d.ts.map +1 -0
  130. package/dist/text.js +454 -0
  131. package/dist/text.js.map +1 -0
  132. package/dist/typed-arrays.d.ts +127 -0
  133. package/dist/typed-arrays.d.ts.map +1 -0
  134. package/dist/typed-arrays.js +410 -0
  135. package/dist/typed-arrays.js.map +1 -0
  136. package/dist/types.d.ts +358 -0
  137. package/dist/types.d.ts.map +1 -0
  138. package/dist/types.js +216 -0
  139. package/dist/types.js.map +1 -0
  140. package/native/annot.cc +557 -0
  141. package/native/buffer.cc +204 -0
  142. package/native/colorspace.cc +166 -0
  143. package/native/context.cc +84 -0
  144. package/native/cookie.cc +179 -0
  145. package/native/device.cc +179 -0
  146. package/native/display_list.cc +179 -0
  147. package/native/document.cc +268 -0
  148. package/native/enhanced.cc +70 -0
  149. package/native/font.cc +282 -0
  150. package/native/form.cc +523 -0
  151. package/native/geometry.cc +255 -0
  152. package/native/image.cc +216 -0
  153. package/native/include/micropdf/enhanced.h +38 -0
  154. package/native/include/micropdf/types.h +36 -0
  155. package/native/include/micropdf.h +106 -0
  156. package/native/include/mupdf-ffi.h +39 -0
  157. package/native/include/mupdf.h +11 -0
  158. package/native/include/mupdf_minimal.h +381 -0
  159. package/native/lib/linux-x64/libmicropdf.a +0 -0
  160. package/native/link.cc +234 -0
  161. package/native/micropdf.cc +71 -0
  162. package/native/output.cc +229 -0
  163. package/native/page.cc +572 -0
  164. package/native/path.cc +259 -0
  165. package/native/pixmap.cc +240 -0
  166. package/native/stext.cc +610 -0
  167. package/native/stream.cc +239 -0
  168. package/package.json +120 -0
  169. package/scripts/build-from-rust.js +97 -0
  170. package/scripts/install.js +184 -0
package/dist/annot.js ADDED
@@ -0,0 +1,697 @@
1
+ /**
2
+ * Annot - PDF annotation handling
3
+ *
4
+ * This module provides comprehensive PDF annotation support with 100% API compatibility
5
+ * with MuPDF's annotation operations. It supports creating, modifying, and managing
6
+ * various types of PDF annotations including text notes, highlights, stamps, shapes,
7
+ * ink annotations, and more.
8
+ *
9
+ * **Key Features:**
10
+ * - 28 annotation types (text, highlight, stamp, ink, shapes, etc.)
11
+ * - Complete annotation properties (color, opacity, borders, etc.)
12
+ * - Annotation lifecycle management (creation, modification, deletion)
13
+ * - Dirty tracking for efficient updates
14
+ * - Reference counting for memory management
15
+ *
16
+ * **Supported Annotation Types:**
17
+ * - **Text Markup**: Highlight, Underline, Squiggly, StrikeOut
18
+ * - **Note Annotations**: Text, FreeText
19
+ * - **Shape Annotations**: Square, Circle, Line, Polygon, PolyLine
20
+ * - **Stamp Annotations**: Stamp (Approved, Draft, etc.)
21
+ * - **Drawing Annotations**: Ink (freehand drawing)
22
+ * - **Special Types**: Link, FileAttachment, Sound, Movie, Widget, etc.
23
+ *
24
+ * @example Basic usage:
25
+ * ```typescript
26
+ * import { Annotation, AnnotationType, AnnotationFlags } from 'micropdf';
27
+ *
28
+ * // Create a text annotation
29
+ * const textAnnot = Annotation.createText(
30
+ * { x0: 100, y0: 100, x1: 150, y1: 120 },
31
+ * 'This is a note'
32
+ * );
33
+ *
34
+ * // Create a highlight annotation
35
+ * const highlightAnnot = Annotation.createHighlight(
36
+ * { x0: 50, y0: 200, x1: 300, y1: 220 },
37
+ * [1, 1, 0] // Yellow
38
+ * );
39
+ *
40
+ * // Modify annotation properties
41
+ * highlightAnnot.opacity = 0.5;
42
+ * highlightAnnot.author = 'John Doe';
43
+ * highlightAnnot.setFlag(AnnotationFlags.Print, true);
44
+ *
45
+ * // Check if annotation was modified
46
+ * if (highlightAnnot.isDirty) {
47
+ * // Update appearance
48
+ * highlightAnnot.update();
49
+ * }
50
+ * ```
51
+ *
52
+ * @module annot
53
+ */
54
+ import { Rect, Point } from './geometry.js';
55
+ /**
56
+ * PDF annotation types.
57
+ *
58
+ * These correspond to the standard PDF annotation types as defined in the PDF specification.
59
+ * Each type has specific rendering behavior and properties.
60
+ *
61
+ * @enum {number}
62
+ */
63
+ export var AnnotationType;
64
+ (function (AnnotationType) {
65
+ /** Text note annotation - sticky note icon */
66
+ AnnotationType[AnnotationType["Text"] = 0] = "Text";
67
+ /** Link annotation - hyperlink to URL or document location */
68
+ AnnotationType[AnnotationType["Link"] = 1] = "Link";
69
+ /** Free text annotation - text directly on page */
70
+ AnnotationType[AnnotationType["FreeText"] = 2] = "FreeText";
71
+ /** Line annotation - straight line with optional endpoints */
72
+ AnnotationType[AnnotationType["Line"] = 3] = "Line";
73
+ /** Square annotation - rectangle shape */
74
+ AnnotationType[AnnotationType["Square"] = 4] = "Square";
75
+ /** Circle annotation - circle/ellipse shape */
76
+ AnnotationType[AnnotationType["Circle"] = 5] = "Circle";
77
+ /** Polygon annotation - closed polygon shape */
78
+ AnnotationType[AnnotationType["Polygon"] = 6] = "Polygon";
79
+ /** PolyLine annotation - open polyline shape */
80
+ AnnotationType[AnnotationType["PolyLine"] = 7] = "PolyLine";
81
+ /** Highlight annotation - text markup highlighting */
82
+ AnnotationType[AnnotationType["Highlight"] = 8] = "Highlight";
83
+ /** Underline annotation - text markup underlining */
84
+ AnnotationType[AnnotationType["Underline"] = 9] = "Underline";
85
+ /** Squiggly annotation - text markup squiggly underline */
86
+ AnnotationType[AnnotationType["Squiggly"] = 10] = "Squiggly";
87
+ /** StrikeOut annotation - text markup strikethrough */
88
+ AnnotationType[AnnotationType["StrikeOut"] = 11] = "StrikeOut";
89
+ /** Stamp annotation - rubber stamp (Approved, Draft, etc.) */
90
+ AnnotationType[AnnotationType["Stamp"] = 12] = "Stamp";
91
+ /** Caret annotation - text insertion point */
92
+ AnnotationType[AnnotationType["Caret"] = 13] = "Caret";
93
+ /** Ink annotation - freehand drawing paths */
94
+ AnnotationType[AnnotationType["Ink"] = 14] = "Ink";
95
+ /** Popup annotation - popup window for another annotation */
96
+ AnnotationType[AnnotationType["Popup"] = 15] = "Popup";
97
+ /** File attachment annotation - embedded file */
98
+ AnnotationType[AnnotationType["FileAttachment"] = 16] = "FileAttachment";
99
+ /** Sound annotation - embedded sound */
100
+ AnnotationType[AnnotationType["Sound"] = 17] = "Sound";
101
+ /** Movie annotation - embedded video */
102
+ AnnotationType[AnnotationType["Movie"] = 18] = "Movie";
103
+ /** Widget annotation - interactive form field */
104
+ AnnotationType[AnnotationType["Widget"] = 19] = "Widget";
105
+ /** Screen annotation - multimedia screen */
106
+ AnnotationType[AnnotationType["Screen"] = 20] = "Screen";
107
+ /** Printer mark annotation - printing marks */
108
+ AnnotationType[AnnotationType["PrinterMark"] = 21] = "PrinterMark";
109
+ /** Trap net annotation - color separation trapping */
110
+ AnnotationType[AnnotationType["TrapNet"] = 22] = "TrapNet";
111
+ /** Watermark annotation - page watermark */
112
+ AnnotationType[AnnotationType["Watermark"] = 23] = "Watermark";
113
+ /** 3D annotation - 3D artwork */
114
+ AnnotationType[AnnotationType["ThreeD"] = 24] = "ThreeD";
115
+ /** Redact annotation - content to be redacted */
116
+ AnnotationType[AnnotationType["Redact"] = 25] = "Redact";
117
+ })(AnnotationType || (AnnotationType = {}));
118
+ /**
119
+ * Annotation flags (bit flags).
120
+ *
121
+ * These flags control the visibility, behavior, and interaction of annotations.
122
+ * Multiple flags can be combined using bitwise OR operations.
123
+ *
124
+ * @example Using annotation flags:
125
+ * ```typescript
126
+ * import { Annotation, AnnotationFlags } from 'micropdf';
127
+ *
128
+ * const annot = Annotation.createText(rect, 'Note');
129
+ *
130
+ * // Set multiple flags
131
+ * annot.setFlags(AnnotationFlags.Print | AnnotationFlags.ReadOnly);
132
+ *
133
+ * // Check if a flag is set
134
+ * if (annot.hasFlag(AnnotationFlags.Print)) {
135
+ * console.log('Annotation will be printed');
136
+ * }
137
+ *
138
+ * // Toggle a flag
139
+ * annot.setFlag(AnnotationFlags.Hidden, true);
140
+ * ```
141
+ *
142
+ * @enum {number}
143
+ */
144
+ export var AnnotationFlags;
145
+ (function (AnnotationFlags) {
146
+ /** Annotation is invisible (not displayed or printed) */
147
+ AnnotationFlags[AnnotationFlags["Invisible"] = 1] = "Invisible";
148
+ /** Annotation is hidden (not displayed, but may be printed) */
149
+ AnnotationFlags[AnnotationFlags["Hidden"] = 2] = "Hidden";
150
+ /** Annotation should be printed */
151
+ AnnotationFlags[AnnotationFlags["Print"] = 4] = "Print";
152
+ /** Annotation should not scale with zoom */
153
+ AnnotationFlags[AnnotationFlags["NoZoom"] = 8] = "NoZoom";
154
+ /** Annotation should not rotate with page */
155
+ AnnotationFlags[AnnotationFlags["NoRotate"] = 16] = "NoRotate";
156
+ /** Annotation should not be viewed (but may be printed) */
157
+ AnnotationFlags[AnnotationFlags["NoView"] = 32] = "NoView";
158
+ /** Annotation is read-only (cannot be modified or deleted) */
159
+ AnnotationFlags[AnnotationFlags["ReadOnly"] = 64] = "ReadOnly";
160
+ /** Annotation is locked (cannot be moved or resized) */
161
+ AnnotationFlags[AnnotationFlags["Locked"] = 128] = "Locked";
162
+ /** Toggle NoView flag based on user actions */
163
+ AnnotationFlags[AnnotationFlags["ToggleNoView"] = 256] = "ToggleNoView";
164
+ /** Annotation contents are locked (cannot be edited) */
165
+ AnnotationFlags[AnnotationFlags["LockedContents"] = 512] = "LockedContents";
166
+ })(AnnotationFlags || (AnnotationFlags = {}));
167
+ /**
168
+ * Line ending styles for line annotations.
169
+ *
170
+ * These styles define the appearance of line endings for Line, PolyLine,
171
+ * and Polygon annotations.
172
+ *
173
+ * @example Using line ending styles:
174
+ * ```typescript
175
+ * import { Annotation, LineEndingStyle } from 'micropdf';
176
+ *
177
+ * const lineAnnot = Annotation.createLine(rect, start, end);
178
+ * lineAnnot.lineStartStyle = LineEndingStyle.OpenArrow;
179
+ * lineAnnot.lineEndStyle = LineEndingStyle.ClosedArrow;
180
+ * ```
181
+ *
182
+ * @enum {number}
183
+ */
184
+ export var LineEndingStyle;
185
+ (function (LineEndingStyle) {
186
+ /** No line ending */
187
+ LineEndingStyle[LineEndingStyle["None"] = 0] = "None";
188
+ /** Square line ending */
189
+ LineEndingStyle[LineEndingStyle["Square"] = 1] = "Square";
190
+ /** Circle line ending */
191
+ LineEndingStyle[LineEndingStyle["Circle"] = 2] = "Circle";
192
+ /** Diamond line ending */
193
+ LineEndingStyle[LineEndingStyle["Diamond"] = 3] = "Diamond";
194
+ /** Open arrow line ending */
195
+ LineEndingStyle[LineEndingStyle["OpenArrow"] = 4] = "OpenArrow";
196
+ /** Closed arrow line ending (filled) */
197
+ LineEndingStyle[LineEndingStyle["ClosedArrow"] = 5] = "ClosedArrow";
198
+ /** Butt line ending (perpendicular cap) */
199
+ LineEndingStyle[LineEndingStyle["Butt"] = 6] = "Butt";
200
+ /** Reverse open arrow */
201
+ LineEndingStyle[LineEndingStyle["ROpenArrow"] = 7] = "ROpenArrow";
202
+ /** Reverse closed arrow (filled) */
203
+ LineEndingStyle[LineEndingStyle["RClosedArrow"] = 8] = "RClosedArrow";
204
+ /** Slash line ending (diagonal cap) */
205
+ LineEndingStyle[LineEndingStyle["Slash"] = 9] = "Slash";
206
+ })(LineEndingStyle || (LineEndingStyle = {}));
207
+ /**
208
+ * A PDF annotation.
209
+ *
210
+ * Represents a single PDF annotation with all its properties and methods.
211
+ * Annotations can be text notes, highlights, shapes, stamps, ink drawings, and more.
212
+ *
213
+ * **Lifecycle:**
214
+ * 1. Create annotation using static factory methods or constructor
215
+ * 2. Modify properties (color, opacity, contents, etc.)
216
+ * 3. Check `isDirty` to see if annotation needs updating
217
+ * 4. Call `update()` to update appearance
218
+ * 5. Increment/decrement reference count for memory management
219
+ * 6. Drop annotation when done (`drop()`)
220
+ *
221
+ * **Properties:**
222
+ * - Type, rectangle, flags
223
+ * - Contents, author, subject
224
+ * - Color, opacity, borders
225
+ * - Line endpoints and styles (for line annotations)
226
+ * - Modification date
227
+ * - Popup association
228
+ *
229
+ * **Methods:**
230
+ * - Getters/setters for all properties
231
+ * - Type checking (`isHighlight()`, `isStamp()`, etc.)
232
+ * - Dirty tracking (`isDirty`, `markDirty()`, `clearDirty()`)
233
+ * - Reference counting (`keep()`, `drop()`)
234
+ * - Appearance updates (`update()`)
235
+ * - Cloning (`clone()`)
236
+ *
237
+ * @example Creating and modifying annotations:
238
+ * ```typescript
239
+ * // Create a highlight annotation
240
+ * const highlight = Annotation.createHighlight(
241
+ * { x0: 100, y0: 200, x1: 400, y1: 220 },
242
+ * [1, 1, 0] // Yellow
243
+ * );
244
+ *
245
+ * // Modify properties
246
+ * highlight.opacity = 0.3;
247
+ * highlight.author = 'John Doe';
248
+ * highlight.contents = 'Important section';
249
+ *
250
+ * // Check if modified
251
+ * if (highlight.isDirty) {
252
+ * highlight.update(); // Update appearance
253
+ * }
254
+ *
255
+ * // Clone annotation
256
+ * const copy = highlight.clone();
257
+ *
258
+ * // Clean up
259
+ * highlight.drop();
260
+ * copy.drop();
261
+ * ```
262
+ *
263
+ * @example Working with different annotation types:
264
+ * ```typescript
265
+ * // Text note
266
+ * const note = Annotation.createText(rect, 'Important!');
267
+ * note.setFlag(AnnotationFlags.ReadOnly, true);
268
+ *
269
+ * // Stamp
270
+ * const stamp = Annotation.createStamp(rect, 'Approved');
271
+ * stamp.color = [0, 1, 0]; // Green
272
+ *
273
+ * // Line with arrows
274
+ * const line = Annotation.createLine(rect, start, end);
275
+ * line.lineStartStyle = LineEndingStyle.OpenArrow;
276
+ * line.lineEndStyle = LineEndingStyle.ClosedArrow;
277
+ *
278
+ * // Free text
279
+ * const freeText = Annotation.createFreeText(rect, 'This is text');
280
+ * freeText.borderWidth = 2;
281
+ * ```
282
+ *
283
+ * @class
284
+ */
285
+ export class Annotation {
286
+ _type;
287
+ _rect;
288
+ _flags = AnnotationFlags.Print;
289
+ _contents = '';
290
+ _author = '';
291
+ _color = [1, 1, 0]; // Yellow default
292
+ _interiorColor = [];
293
+ _borderWidth = 1;
294
+ _opacity = 1.0;
295
+ _lineStart = Point.ORIGIN;
296
+ _lineEnd = Point.ORIGIN;
297
+ _refCount = 1;
298
+ _dirty = false;
299
+ _hasPopup = false;
300
+ /**
301
+ * Creates a new PDF annotation.
302
+ *
303
+ * **Note**: Prefer using static factory methods (e.g., `createHighlight()`, `createStamp()`)
304
+ * instead of the constructor for better type safety and convenience.
305
+ *
306
+ * @param type - The annotation type
307
+ * @param rect - The annotation rectangle on the page
308
+ *
309
+ * @example Using the constructor:
310
+ * ```typescript
311
+ * const annot = new Annotation(AnnotationType.Square, {
312
+ * x0: 100, y0: 100, x1: 200, y1: 200
313
+ * });
314
+ * ```
315
+ */
316
+ constructor(type, rect) {
317
+ this._type = type;
318
+ this._rect = Rect.from(rect);
319
+ }
320
+ /**
321
+ * Create a new annotation (alias for constructor).
322
+ *
323
+ * @param type - The annotation type
324
+ * @param rect - The annotation rectangle
325
+ * @returns A new annotation instance
326
+ *
327
+ * @deprecated Use static factory methods instead (e.g., `createHighlight()`)
328
+ */
329
+ static create(type, rect) {
330
+ return new Annotation(type, rect);
331
+ }
332
+ // ============================================================================
333
+ // Reference Counting
334
+ // ============================================================================
335
+ keep() {
336
+ this._refCount++;
337
+ return this;
338
+ }
339
+ drop() {
340
+ if (this._refCount > 0) {
341
+ this._refCount--;
342
+ }
343
+ }
344
+ /**
345
+ * Clone this annotation
346
+ */
347
+ clone() {
348
+ const cloned = new Annotation(this._type, this._rect);
349
+ cloned._flags = this._flags;
350
+ cloned._contents = this._contents;
351
+ cloned._author = this._author;
352
+ cloned._color = [...this._color];
353
+ cloned._interiorColor = [...this._interiorColor];
354
+ cloned._borderWidth = this._borderWidth;
355
+ cloned._opacity = this._opacity;
356
+ cloned._lineStart = this._lineStart;
357
+ cloned._lineEnd = this._lineEnd;
358
+ cloned._hasPopup = this._hasPopup;
359
+ return cloned;
360
+ }
361
+ // ============================================================================
362
+ // Basic Properties
363
+ // ============================================================================
364
+ get type() {
365
+ return this._type;
366
+ }
367
+ get rect() {
368
+ return this._rect;
369
+ }
370
+ set rect(r) {
371
+ this._rect = Rect.from(r);
372
+ this._dirty = true;
373
+ }
374
+ // ============================================================================
375
+ // Flags
376
+ // ============================================================================
377
+ get flags() {
378
+ return this._flags;
379
+ }
380
+ set flags(f) {
381
+ this._flags = f;
382
+ this._dirty = true;
383
+ }
384
+ hasFlag(flag) {
385
+ return (this._flags & flag) !== 0;
386
+ }
387
+ setFlag(flag, value) {
388
+ if (value) {
389
+ this._flags |= flag;
390
+ }
391
+ else {
392
+ this._flags &= ~flag;
393
+ }
394
+ this._dirty = true;
395
+ }
396
+ get isHidden() {
397
+ return this.hasFlag(AnnotationFlags.Hidden);
398
+ }
399
+ set isHidden(value) {
400
+ this.setFlag(AnnotationFlags.Hidden, value);
401
+ }
402
+ get isPrintable() {
403
+ return this.hasFlag(AnnotationFlags.Print);
404
+ }
405
+ set isPrintable(value) {
406
+ this.setFlag(AnnotationFlags.Print, value);
407
+ }
408
+ get isReadOnly() {
409
+ return this.hasFlag(AnnotationFlags.ReadOnly);
410
+ }
411
+ set isReadOnly(value) {
412
+ this.setFlag(AnnotationFlags.ReadOnly, value);
413
+ }
414
+ get isLocked() {
415
+ return this.hasFlag(AnnotationFlags.Locked);
416
+ }
417
+ set isLocked(value) {
418
+ this.setFlag(AnnotationFlags.Locked, value);
419
+ }
420
+ // ============================================================================
421
+ // Content Properties
422
+ // ============================================================================
423
+ get contents() {
424
+ return this._contents;
425
+ }
426
+ set contents(text) {
427
+ this._contents = text;
428
+ this._dirty = true;
429
+ }
430
+ get author() {
431
+ return this._author;
432
+ }
433
+ set author(name) {
434
+ this._author = name;
435
+ this._dirty = true;
436
+ }
437
+ // ============================================================================
438
+ // Appearance Properties
439
+ // ============================================================================
440
+ get color() {
441
+ return [...this._color];
442
+ }
443
+ set color(rgb) {
444
+ if (rgb.length === 3) {
445
+ this._color = [...rgb];
446
+ this._dirty = true;
447
+ }
448
+ }
449
+ get interiorColor() {
450
+ return [...this._interiorColor];
451
+ }
452
+ set interiorColor(rgb) {
453
+ if (rgb.length === 3 || rgb.length === 0) {
454
+ this._interiorColor = [...rgb];
455
+ this._dirty = true;
456
+ }
457
+ }
458
+ get borderWidth() {
459
+ return this._borderWidth;
460
+ }
461
+ set borderWidth(width) {
462
+ this._borderWidth = Math.max(0, width);
463
+ this._dirty = true;
464
+ }
465
+ get opacity() {
466
+ return this._opacity;
467
+ }
468
+ set opacity(alpha) {
469
+ this._opacity = Math.max(0, Math.min(1, alpha));
470
+ this._dirty = true;
471
+ }
472
+ // ============================================================================
473
+ // Line Annotation Properties
474
+ // ============================================================================
475
+ get lineStart() {
476
+ return this._lineStart;
477
+ }
478
+ get lineEnd() {
479
+ return this._lineEnd;
480
+ }
481
+ setLine(start, end) {
482
+ this._lineStart = Point.from(start);
483
+ this._lineEnd = Point.from(end);
484
+ this._dirty = true;
485
+ }
486
+ getLine() {
487
+ return [this._lineStart, this._lineEnd];
488
+ }
489
+ // ============================================================================
490
+ // Popup
491
+ // ============================================================================
492
+ get hasPopup() {
493
+ return this._hasPopup;
494
+ }
495
+ set hasPopup(value) {
496
+ this._hasPopup = value;
497
+ this._dirty = true;
498
+ }
499
+ // ============================================================================
500
+ // Dirty Tracking
501
+ // ============================================================================
502
+ get isDirty() {
503
+ return this._dirty;
504
+ }
505
+ clearDirty() {
506
+ this._dirty = false;
507
+ }
508
+ /**
509
+ * Update the annotation (mark for re-rendering)
510
+ */
511
+ update() {
512
+ this._dirty = true;
513
+ }
514
+ // ============================================================================
515
+ // Validation
516
+ // ============================================================================
517
+ isValid() {
518
+ // Check if annotation has valid properties
519
+ if (!this._rect || this._rect.isEmpty) {
520
+ return false;
521
+ }
522
+ if (this._opacity < 0 || this._opacity > 1) {
523
+ return false;
524
+ }
525
+ if (this._borderWidth < 0) {
526
+ return false;
527
+ }
528
+ return true;
529
+ }
530
+ // ============================================================================
531
+ // Type-specific factory methods
532
+ // ============================================================================
533
+ /**
534
+ * Create a text note annotation
535
+ */
536
+ static createText(rect, contents = '', author = '') {
537
+ const annot = new Annotation(AnnotationType.Text, rect);
538
+ annot.contents = contents;
539
+ annot.author = author;
540
+ return annot;
541
+ }
542
+ /**
543
+ * Create a highlight annotation
544
+ */
545
+ static createHighlight(rect, color = [1, 1, 0]) {
546
+ const annot = new Annotation(AnnotationType.Highlight, rect);
547
+ annot.color = color;
548
+ annot.opacity = 0.5;
549
+ return annot;
550
+ }
551
+ /**
552
+ * Create an underline annotation
553
+ */
554
+ static createUnderline(rect, color = [1, 0, 0]) {
555
+ const annot = new Annotation(AnnotationType.Underline, rect);
556
+ annot.color = color;
557
+ return annot;
558
+ }
559
+ /**
560
+ * Create a strikeout annotation
561
+ */
562
+ static createStrikeOut(rect, color = [1, 0, 0]) {
563
+ const annot = new Annotation(AnnotationType.StrikeOut, rect);
564
+ annot.color = color;
565
+ return annot;
566
+ }
567
+ /**
568
+ * Create a squiggly underline annotation
569
+ */
570
+ static createSquiggly(rect, color = [1, 0, 0]) {
571
+ const annot = new Annotation(AnnotationType.Squiggly, rect);
572
+ annot.color = color;
573
+ return annot;
574
+ }
575
+ /**
576
+ * Create a line annotation
577
+ */
578
+ static createLine(rect, start, end, color = [0, 0, 0]) {
579
+ const annot = new Annotation(AnnotationType.Line, rect);
580
+ annot.setLine(start, end);
581
+ annot.color = color;
582
+ return annot;
583
+ }
584
+ /**
585
+ * Create a square annotation
586
+ */
587
+ static createSquare(rect, color = [0, 0, 0]) {
588
+ const annot = new Annotation(AnnotationType.Square, rect);
589
+ annot.color = color;
590
+ return annot;
591
+ }
592
+ /**
593
+ * Create a circle annotation
594
+ */
595
+ static createCircle(rect, color = [0, 0, 0]) {
596
+ const annot = new Annotation(AnnotationType.Circle, rect);
597
+ annot.color = color;
598
+ return annot;
599
+ }
600
+ /**
601
+ * Create an ink annotation (freehand drawing)
602
+ */
603
+ static createInk(rect, color = [0, 0, 0]) {
604
+ const annot = new Annotation(AnnotationType.Ink, rect);
605
+ annot.color = color;
606
+ return annot;
607
+ }
608
+ /**
609
+ * Create a stamp annotation
610
+ */
611
+ static createStamp(rect, stampText = 'Approved') {
612
+ const annot = new Annotation(AnnotationType.Stamp, rect);
613
+ annot.contents = stampText;
614
+ return annot;
615
+ }
616
+ /**
617
+ * Create a free text annotation
618
+ */
619
+ static createFreeText(rect, text = '') {
620
+ const annot = new Annotation(AnnotationType.FreeText, rect);
621
+ annot.contents = text;
622
+ return annot;
623
+ }
624
+ }
625
+ /**
626
+ * Annotation list manager for a page
627
+ */
628
+ export class AnnotationList {
629
+ _annotations = [];
630
+ constructor() { }
631
+ /**
632
+ * Add an annotation
633
+ */
634
+ add(annot) {
635
+ this._annotations.push(annot);
636
+ }
637
+ /**
638
+ * Delete an annotation
639
+ */
640
+ delete(annot) {
641
+ const index = this._annotations.indexOf(annot);
642
+ if (index >= 0) {
643
+ this._annotations.splice(index, 1);
644
+ return true;
645
+ }
646
+ return false;
647
+ }
648
+ /**
649
+ * Get annotation count
650
+ */
651
+ get count() {
652
+ return this._annotations.length;
653
+ }
654
+ /**
655
+ * Get annotation by index
656
+ */
657
+ get(index) {
658
+ return this._annotations[index];
659
+ }
660
+ /**
661
+ * Get first annotation
662
+ */
663
+ first() {
664
+ return this._annotations[0];
665
+ }
666
+ /**
667
+ * Get next annotation after the given one
668
+ */
669
+ next(current) {
670
+ const index = this._annotations.indexOf(current);
671
+ if (index >= 0 && index < this._annotations.length - 1) {
672
+ return this._annotations[index + 1];
673
+ }
674
+ return undefined;
675
+ }
676
+ /**
677
+ * Get all annotations
678
+ */
679
+ getAll() {
680
+ return [...this._annotations];
681
+ }
682
+ /**
683
+ * Clear all annotations
684
+ */
685
+ clear() {
686
+ this._annotations = [];
687
+ }
688
+ /**
689
+ * Iterate over annotations
690
+ */
691
+ *[Symbol.iterator]() {
692
+ for (const annot of this._annotations) {
693
+ yield annot;
694
+ }
695
+ }
696
+ }
697
+ //# sourceMappingURL=annot.js.map