Release v2.14.0
- #581 by @bobsingor – Support callout free text in the PDFium executor: read/write
/CL,/LE,/IT, stroke width and colors,/TextColor, and remap rectangle differences (/RD) between native PDFium order and the model shape.
- #581 by @bobsingor – Extend free text annotation typing for callouts: add
PdfAnnotationColorType.TextColorand optionalcalloutLine,lineEnding,strokeWidth, andstrokeColoronPdfFreeTextAnnoObject.
- #581 by @bobsingor – Expose EmbedPDF callout line helpers in the WASM bindings (
EPDFAnnot_GetCalloutLineCount,EPDFAnnot_GetCalloutLine,EPDFAnnot_SetCalloutLine) and refresh bundledpdfium.js/pdfium.cjs/pdfium.wasm.
- #581 by @bobsingor – Add callout free text (
FreeTextCallout): creation handler and preview data, vertex config and patch pipeline, defaultfreeTextCallouttool, and built-in renderers for React, Vue, and Svelte (including preview components and sharedcalloutVertexConfig).
- #581 by @bobsingor – Wire callout into the snippet viewer: callout icon,
annotation:add-calloutcommand, annotation toolbar and overflow menu entries, translations, and sidebar property schema forfreeTextCallout(including opaque stroke color control).
Release v2.13.0
- #579 by @bobsingor – Add the Signature plugin: reusable signature and initials entries, draw/type/upload pads, placement as ink or stamp annotations, and framework bindings for React, Vue, Preact, and Svelte.
- #579 by @bobsingor – Re-export patching utilities from
./patchingso dependent plugins (for example signature placement) can reuse the shared patch helpers.
- #579 by @bobsingor – Register the Signature plugin in the snippet viewer, add a create-signature modal and wire the signature sidebar to real entries, placement, and translations.
Release v2.12.1
- #571 by @bobsingor – Add
getAnnotations(options?)method to retrieve all tracked annotations, optionally filtered by page index. Available on bothAnnotationCapabilityandAnnotationScope.
- #571 by @bobsingor – Export missing annotation types from the snippet package:
AnnotationTransferItem,ExportAnnotationsOptions,GetAnnotationsOptions,TrackedAnnotation,AnnotationTool,PdfAnnotationSubtype, andPdfStampAnnoObject.
Release v2.12.0
- #569 by @bobsingor – Add symmetric annotation import/export API using a unified
AnnotationTransferItemtype.exportAnnotations()produces the same format thatimportAnnotations()consumes — zero remapping needed for round-tripping. Stamp appearances are automatically exported as PDF buffers inctx.data. On import, stamps can be created from PNG, JPEG, or PDF buffers viactx: { data: ArrayBuffer }— the engine auto-detects the format from magic bytes. Also addsdeleteAllAnnotations()convenience method.
Release v2.11.1
-
#557 by @jonashaag – Add BMP encoding support as an optional image format
BMP encoding bypasses canvas.toBlob() entirely by prepending a 66-byte header to the raw RGBA pixel data. This eliminates the dominant rendering bottleneck — in benchmarks, encoding dropped from ~76ms average (PNG via canvas.toBlob) to <1ms, reducing total tile render time by ~60%.
The BMP uses BI_BITFIELDS with channel masks matching PDFium's RGBA output byte order, so no per-pixel conversion is needed. Top-down row order avoids row flipping. The result is a valid BMP that all modern browsers decode natively in
<img>elements.Users who want to opt into the faster BMP path can set
defaultImageType: 'image/bmp'in the render plugin config, while PNG remains the default output format. -
#566 by @bobsingor – Fix custom stamp annotations with
imageSizeso predefined image stamps render correctly while preserving the original embedded bitmap quality.
-
#557 by @jonashaag – Add BMP encoding support as an optional image format
BMP encoding bypasses canvas.toBlob() entirely by prepending a 66-byte header to the raw RGBA pixel data. This eliminates the dominant rendering bottleneck — in benchmarks, encoding dropped from ~76ms average (PNG via canvas.toBlob) to <1ms, reducing total tile render time by ~60%.
The BMP uses BI_BITFIELDS with channel masks matching PDFium's RGBA output byte order, so no per-pixel conversion is needed. Top-down row order avoids row flipping. The result is a valid BMP that all modern browsers decode natively in
<img>elements.Users who want to opt into the faster BMP path can set
defaultImageType: 'image/bmp'in the render plugin config, while PNG remains the default output format.
- #566 by @bobsingor – Fix Vue and Svelte renderer registration typing so custom preview container styles build correctly.
-
#557 by @jonashaag – Add BMP encoding support as an optional image format
BMP encoding bypasses canvas.toBlob() entirely by prepending a 66-byte header to the raw RGBA pixel data. This eliminates the dominant rendering bottleneck — in benchmarks, encoding dropped from ~76ms average (PNG via canvas.toBlob) to <1ms, reducing total tile render time by ~60%.
The BMP uses BI_BITFIELDS with channel masks matching PDFium's RGBA output byte order, so no per-pixel conversion is needed. Top-down row order avoids row flipping. The result is a valid BMP that all modern browsers decode natively in
<img>elements.Users who want to opt into the faster BMP path can set
defaultImageType: 'image/bmp'in the render plugin config, while PNG remains the default output format.
- #566 by @bobsingor – Disable the snippet rubber stamp insert command when the active document does not allow annotation modifications.
Release v2.11.0
- #562 by @bobsingor – Implement new PDF manipulation and annotation appearance export methods:
createDocument,importPages,deletePage,exportAnnotationAppearanceAsPdf, andexportAnnotationsAppearanceAsPdf.
- #562 by @bobsingor – Add
PdfAnnotationNameenum (deprecatingPdfAnnotationIcon). ExtendPdfEngineandIPdfiumExecutorinterfaces with new document manipulation capabilities (createDocument,importPages,deletePage) and annotation appearance export methods.
- #562 by @bobsingor – Expose new PDFium functions for annotation appearance generation and export (
EPDFAnnot_ExportAppearanceAsDocument,EPDFAnnot_ExportMultipleAppearancesAsDocument,EPDFAnnot_SetAppearanceFromPage,EPDFAnnot_GetName,EPDFAnnot_SetName).
- #562 by @bobsingor – Add
ToolContextMapto support typed context injection for active tools. Introduce preview renderers and bounding-box components for annotations (CirclePreview,SquarePreview,InkPreview, etc.) to support drag-to-create or stamp hover previews.
- #562 by @bobsingor – Introduce
@embedpdf/plugin-stampfor managing reusable rubber-stamp libraries. Includes features for loading built-in/manifest stamps, creating custom stamps from annotations, and exporting custom stamp libraries.
- #562 by @bobsingor – Enhance sidebar API by allowing custom
propsto be passed viasetActiveSidebarandtoggleSidebar, enabling dynamic state injection into sidebar components.
- #562 by @bobsingor – Integrate
@embedpdf/plugin-stampwith the default viewer. Add the Rubber Stamp sidebar, Signature sidebar, and Insert tools to the default UI schema. Include standard stamp/insert translations.
Release v2.10.1
Automated release.
Release v2.10.0
- #537 by @bobsingor –
- Add engine APIs for reading page widgets and form/document JavaScript actions, setting full widget state, renaming and sharing widget fields, and regenerating widget appearances.
- Route the new widget and form operations through the PDFium and web worker layers to support form authoring and fill-mode workflows.
- #537 by @bobsingor –
- Expand form and widget models with typed field unions, widget appearance/style metadata, export values, and JavaScript action types.
- Add helper utilities and engine interface updates for widget discovery, field state updates, shared fields, and appearance regeneration.
- #537 by @bobsingor –
- Add PDFium bindings and wasm exports for creating and editing form widgets, reading widget metadata and JavaScript actions, sharing fields, and regenerating widget appearance streams.
- Improve form handle lifecycle management so widget reads, writes, and appearance generation work more reliably across repeated operations.
- #537 by @bobsingor –
- Add annotation lock modes, scoped navigation/state events, richer tool metadata, and locked-mode renderer support so annotations can switch cleanly between authoring and fill interactions.
- Add link previews and locked link navigation support plus shared React, Svelte, and Vue updates for the new renderer and interaction APIs.
- #537 by @bobsingor –
- Add a new cross-framework form plugin with widget authoring tools, renderer registration, fill-mode components, state hooks, and widget appearance rendering.
- Support text fields, checkboxes, radio buttons, combo boxes, and list boxes across React, Svelte, Vue, and Preact, including programmatic updates and shared field operations.
- #537 by @bobsingor –
- Add full form authoring and fill-mode support to the snippet viewer, including new commands, toolbar items, translations, icons, and widget editing controls.
- Wire form mode into the viewer schema and sidebars so widgets can be created, configured, filled, and previewed in the example app.
- #537 by @bobsingor –
- Allow
TabandShift+Tabkeyboard handling to continue working inside form inputs so field navigation is not blocked. - Normalize spacebar shortcut parsing so commands can consistently match the
spacekey.
- Allow
- #537 by @bobsingor –
- Update redaction tool integration to work with typed annotation tool definitions and the newer annotation capability access patterns.
- Guard annotation capability usage during redaction flows and resolve defaults from the active tool configuration for more consistent behavior.
Release v2.9.1
- #532 by @bobsingor – FreeText annotation improvements:
- Fix FreeText editing blocked by interaction layer after the visual/interaction layer split. When
isEditingis true, pointer events now correctly reach the text content in the visual layer while the interaction layer becomes passive. - Add
editAfterCreatetool behavior: FreeText annotations automatically enter editing mode after creation, with the default text fully selected so typing immediately replaces it. - Prevent accidental annotation creation when exiting FreeText editing mode by clicking the page background (
stopImmediatePropagation). - Normalize NBSP characters (
\u00A0) to regular spaces when reading text from contenteditable on blur. - Fix Vue FreeText editing initialization timing so
editAfterCreateworks correctly on first mount.
- Fix FreeText editing blocked by interaction layer after the visual/interaction layer split. When
Release v2.9.0
- #529 by @bobsingor – Integrate cloudy border effect reading and writing in the PDFium engine. Annotations with
/BE /S /Cdictionaries now includecloudyBorderIntensityin their parsed objects, and creating/updating annotations writes the border effect dictionary viasetBorderEffect.
-
#514 by @bobsingor – Expose PDF annotation blend mode in base PDFium annotation properties.
PdfiumNativenow readsEPDFAnnot_GetBlendModeand includesblendModein the shared base annotation payload, so all annotation types parsed through the PDFium engine consistently receive their blend mode metadata.
- #529 by @bobsingor – Add
cloudyBorderIntensityproperty toPdfPolygonAnnoObjectfor cloudy border support on polygon annotations.
- #529 by @bobsingor – Add cloudy border AP generation in PDFium C++. New
cpdf_cloudy_border.cpp/.hgenerates scalloped border paths for Square, Circle, and Polygon annotations via the/BEborder effect dictionary. ExposesEPDFAnnot_SetBorderEffectandEPDFAnnot_ClearBorderEffectbindings.
-
#526 by @bobsingor – Fix
EPDF_GetPageSizeByIndexNormalizedreturning incorrect dimensions for PDFs with inherited MediaBox/CropBox.The function read
/MediaBoxand/CropBoxdirectly from the page dictionary viadict->GetRectFor(), which does not resolve PDF page tree attribute inheritance. Pages that inherit these attributes from a parent/Pagesnode would silently fall back to the default 612x792 (US Letter) size.Replaced the direct dictionary lookups with a
GetInheritedRecthelper that walks the/Parentchain, mirroring the inheritance logic used byCPDF_Page::GetPageAttr. The function remains lightweight (noCPDF_Pageconstruction) while correctly resolving inherited attributes.
- #529 by @bobsingor – Add cloudy border support for Circle, Square, and Polygon annotations across React, Vue, and Svelte renderers. Includes a framework-agnostic SVG path generator (
cloudy-border.ts), conditional rendering of scalloped<path>elements withstroke-linejoin: round, cloudy-aware hit areas, rectangle differences computation in handlers and patch functions, and polygon preview support.
-
#517 by @sebabal – Fix link annotation click not working in the Vue build.
The template expression
@pointerdown="hasIRT ? undefined : onClick"compiled to a function that returned theonClickreference instead of invoking it. Changed toonClick?.($event)so the handler is actually called on pointer down, restoring link selection and navigation. Thanks to @sebabal -
#530 by @bobsingor – Hide the group selection menu while group rotation is active. Previously the menu remained visible during rotation, which could overlap with rotation guide lines and the tooltip. This aligns the group selection box behavior with the single-annotation container, which already hides its menu during rotation.
-
#512 by @bobsingor – Add smart line recognition to the ink handler with horizontal/vertical axis snapping.
When
smartLineRecognitionis enabled on an ink tool, straight strokes drawn close to a horizontal or vertical axis are automatically snapped to a clean two-point line afterpointerUp. The snapped line is centred on the average position of all recorded points rather than being anchored to the start point. Diagonal straight strokes (outside the snap cone) are left untouched with their original points intact.New
InkBehaviorfields onAnnotationTool:snapAngleDeg— degrees from horizontal/vertical within which snapping is applied (default15). Strokes whose angle falls outside both snap zones are not reduced to two points.
- #529 by @bobsingor – Add cloudy border intensity options to the stroke style picker in the annotation sidebar for Circle, Square, and Polygon tools. Includes realistic semicircular arc SVG previews for intensity 1 and 2.
-
#512 by @bobsingor – Add
annotation:add-ink-highlightercommand and toolbar button for the ink highlighter tool.The command toggles the
inkHighlightertool, respects theModifyAnnotationspermission, and is registered under theannotationandannotation-inkcategories. The corresponding button is inserted into all relevant toolbar and mobile-menu slots next to the existing ink pen button.