Skip to content

Render signed signatures and initials with a wrapped credibility treatment#663

Open
jmkritt wants to merge 1 commit into
docusealco:masterfrom
jmkritt:signed-signature-wrap-credibility
Open

Render signed signatures and initials with a wrapped credibility treatment#663
jmkritt wants to merge 1 commit into
docusealco:masterfrom
jmkritt:signed-signature-wrap-credibility

Conversation

@jmkritt

@jmkritt jmkritt commented May 6, 2026

Copy link
Copy Markdown

Problem

The current rendering of signed signatures in the result PDF places the signature image with an optional plain-text "ID + Digitally signed by NAME + timestamp" caption beside or below it depending on field aspect ratio. Signed initials get no caption — just a bare image. There's no consistent visual framing.

Compared to industry-standard outputs (DocuSign, Adobe Sign), recipients of DocuSeal-signed PDFs see a plainer rendering that doesn't match the bracketed signature visual conventions they're accustomed to. In real-estate transactions specifically, where title companies, lenders, and counterparties have learned what a "properly signed contract" looks like through years of DocuSign exposure, the plainer style can read as less polished — even when the underlying validity is identical.

Motivation

Built for a residential real-estate signing workflow where clients and title companies are accustomed to the bracketed signature visual format. Sharing upstream in case it's useful — happy to iterate on the design, split into smaller commits, or close the PR if it doesn't fit DocuSeal's design preferences. No demonstrated upstream demand for this — just one user's contribution from real-world use.

Change

Adds a "wrap" credibility treatment for signed signature and initials fields:

  • Left-side amber bracket rendered via HexaPDF path drawing in generate_result_attachments.rb, height matched to the signature image, asymmetric bottom-stub flourish.
  • Header in Helvetica-Bold: Digitally signed by: for signatures, Initials: for initials.
  • Centered signature image scaled to fit available space.
  • Truncated document ID below the signature (signature only — initials drop the caption to fit small fields).
  • Adaptive layout: counts how many footer lines fit at the rendered field size; drops the ID line first, then the caption line, before crushing the image.
  • Mirrored treatment in the live signing UI (area.vue) and the post-sign view (_value.html.erb) so what the signer sees during review matches the generated PDF.
  • Typed-initials font alias fix in generate_font_image.rb: switched from Go Noto Bold to Dancing Script. Matches the typed signature font (which is already Dancing Script), fixing the visual inconsistency where typed signatures rendered cursive but typed initials rendered sans-serif.

Trade-offs and decisions

  • Helvetica vs Go Noto for the bracket text: Helvetica is one of the 14 standard PDF fonts and keeps the credibility text crisp. Non-Latin scripts (CJK, Arabic, Hebrew) won't render in the bracket header — Helvetica falls back to whatever it has for those locales. The signature image itself still renders correctly using the existing Go Noto Unicode font. Open to suggestions if upstream prefers a Unicode-safe typography choice.
  • Default behavior unchanged: the wrap is only rendered when with_signature_id is enabled (existing config flag, default false). Existing users who haven't opted in see no change.
  • No data-model change: pure rendering layer. No new fields, no new configs, no migration.

Diff size

4 files, +210 −151 lines (most of it the HexaPDF drawing in the result-attachments generator).

Notes

Happy to provide screenshots if helpful — the visual is hard to convey from the diff alone.

…tment

Adds a "wrap" visual treatment to signed signature and initials fields
in the result PDF, the live signing UI, and the post-sign view, so
recipients see a consistent bracketed layout matching industry-standard
signed-document conventions (DocuSign / Adobe Sign etc.).

Motivation
----------
Built for a residential real-estate signing workflow where
clients and title companies are accustomed to the bracketed signature
visual format. The current DocuSeal output is a centered signature image
with optional plain-text caption beside or below it; signed initials are
a bare image with no caption. This change closes the visual gap as an
opt-in style — only renders when with_signature_id is enabled (existing
config flag, default false). Sharing in case useful upstream; happy to
iterate on the design or split into smaller commits.

Change
------
- HexaPDF rendering rewrite in lib/submissions/generate_result_attachments.rb:
  - Left-side amber bracket via path drawing, height matched to image
  - Centered signature image
  - Helvetica-Bold header ("Digitally signed by:" / "Initials:")
  - Optional caption (name + timestamp) and truncated document ID
  - Adaptive layout: drops ID line, then caption line, before crushing
    the image when field is small
  - Page-derived font sizing so signatures and initials match
- Mirrored layout in the live signing UI (app/javascript/submission_form/area.vue)
  and the post-sign view (app/views/submissions/_value.html.erb) so the
  signer's review and the completed-submission page match the PDF
- Typed initials font alias in lib/submitters/generate_font_image.rb
  switched from Go Noto Bold to Dancing Script — matches the typed
  signature font, fixing the visual inconsistency where typed signatures
  rendered cursive but typed initials rendered sans-serif

Trade-offs
----------
- Helvetica vs Go Noto for header/caption: Helvetica is one of the 14
  standard PDF fonts, keeps the credibility text crisp. Non-Latin
  scripts in the bracket text fall back to Helvetica's coverage.
  The signature image itself still renders correctly using Go Noto.
- No data-model change. Pure rendering layer.
- Default behavior unchanged for existing users (with_signature_id
  is still false by default in upstream).

Out of scope
------------
- Strikethrough field unhide (separate PR)
- Default-flag flips for with_signature_id, with_disclosure (opinionated)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant