πŸ—‚οΈ JSON Renderer β€” Form 1040

Use ObviousPDF.Json to generate a complete, accessible, interactive IRS Form 1040 PDF directly from a JSON document definition β€” no C# PDF-building code required.

πŸ“¦ Installation

The JSON renderer ships as a separate NuGet package. Install it alongside the core library:

dotnet add package ObviousPDF
dotnet add package ObviousPDF.Json

Or via the Visual Studio Package Manager:

Install-Package ObviousPDF
Install-Package ObviousPDF.Json

ObviousPDF.Json declares ObviousPDF as a dependency β€” installing the Json package is sufficient.

Render Form 1040 from JSON
using ObviousPDF.Json;

// Render straight from a JSON file to a PDF file
PdfJsonRenderer.RenderFromFile(
    jsonPath:   "form-1040.json",
    outputPath: "form-1040.pdf");

// β€” or β€” render from a JSON string in memory
string json = File.ReadAllText("form-1040.json");
PdfJsonRenderer.Render(json, "form-1040.pdf");

// β€” or β€” render to a stream (e.g. HTTP response)
using var stream = File.OpenWrite("form-1040.pdf");
PdfJsonRenderer.Render(json, stream);

// β€” or β€” build a PdfDocument for further manipulation
// (e.g. merge, split, accessibility check)
using ObviousPDF;
using ObviousPDF.Accessibility;

PdfDocument doc = PdfJsonRenderer.BuildDocument(json);
var checker = new PdfAccessibilityChecker();
var report  = checker.Check(doc);
doc.Save("form-1040.pdf");
Imports ObviousPDF.Json

' Render straight from a JSON file to a PDF file
PdfJsonRenderer.RenderFromFile(
    jsonPath:="form-1040.json",
    outputPath:="form-1040.pdf")

' Or render from a JSON string
Dim json As String = File.ReadAllText("form-1040.json")
PdfJsonRenderer.Render(json, "form-1040.pdf")

' Or build a PdfDocument for further manipulation
Imports ObviousPDF
Imports ObviousPDF.Accessibility

Dim doc As PdfDocument = PdfJsonRenderer.BuildDocument(json)
Dim checker As New PdfAccessibilityChecker()
Dim report = checker.Check(doc)
doc.Save("form-1040.pdf")
open ObviousPDF.Json

// Render straight from a JSON file to a PDF file
PdfJsonRenderer.RenderFromFile(
    jsonPath   = "form-1040.json",
    outputPath = "form-1040.pdf")

// Or render from a JSON string in memory
let json = System.IO.File.ReadAllText("form-1040.json")
PdfJsonRenderer.Render(json, "form-1040.pdf")

// Or build a PdfDocument for further manipulation
open ObviousPDF
open ObviousPDF.Accessibility

let doc     = PdfJsonRenderer.BuildDocument(json)
let checker = PdfAccessibilityChecker()
let report  = checker.Check(doc)
doc.Save("form-1040.pdf")
Add-Type -Path "ObviousPDF.dll"
Add-Type -Path "ObviousPDF.Json.dll"

# Render straight from a JSON file to a PDF file
[ObviousPDF.Json.PdfJsonRenderer]::RenderFromFile(
    "form-1040.json",
    "form-1040.pdf")

# Or render from a JSON string
$json = Get-Content "form-1040.json" -Raw
[ObviousPDF.Json.PdfJsonRenderer]::Render($json, "form-1040.pdf")

# Or build a PdfDocument for further manipulation
$doc     = [ObviousPDF.Json.PdfJsonRenderer]::BuildDocument($json)
$checker = [ObviousPDF.Accessibility.PdfAccessibilityChecker]::new()
$report  = $checker.Check($doc)
$doc.Save("c:\temp\form-1040.pdf")

The sample form-1040.json file is a complete 3-page IRS Form 1040 (2024) with Schedule 1. It includes interactive form fields (text, checkbox, dropdown), an accessible tagged structure tree, embedded font references, and a diagonal SAMPLE watermark on every page. Pass it directly to PdfJsonRenderer.RenderFromFile() to produce the PDF.

Rendered Form 1040 PDF showing Page 1 with Filing Status, Name and Address, Income, and Adjustments to Income sections with interactive form fields and diagonal SAMPLE watermark
Form 1040 Page 1 preview with interactive fields and watermark

JSON Document Schema Overview

A JSON document passed to PdfJsonRenderer follows this top-level structure:

JSON Document Structure
{
  "coordinateOrigin": "topLeft",   // "topLeft" (y↓) or "bottomLeft" (y↑, PDF default)
  "tagged": true,                   // true β†’ Tagged PDF / PDF/UA output
  "accessible": true,               // shorthand: enables tagged + PDF/UA + auto-tagging
  "language": "en-US",              // BCP-47 document language

  "document": {
    "title": "Form 1040 (2024)",
    "author": "Internal Revenue Service",
    "subject": "U.S. Individual Income Tax Return"
  },

  "fonts": [
    { "id": "title-font",  "family": "Helvetica", "style": "Bold" },
    { "id": "body-font",   "family": "Helvetica" },
    { "id": "courier-font","family": "Courier" }
  ],

  "outlines": [
    { "title": "Page 1 β€” Income",    "pageIndex": 0 },
    { "title": "Page 2 β€” Tax",       "pageIndex": 1 },
    { "title": "Schedule 1",          "pageIndex": 2 }
  ],

  "structureTree": {
    "type": "Document",
    "children": [
      { "id": "h1-title",   "type": "H1" },
      { "id": "p-line-1a",  "type": "P"  }
    ]
  },

  "pages": [
    {
      "size": "Letter",
      "content": [
        { "type": "text",      "text": "Form 1040",
          "x": 36, "y": 18,   "structureId": "h1-title",
          "options": { "fontRef": "title-font", "fontSize": 24 } },

        { "type": "textField", "name": "wages",
          "x": 490, "y": 349, "width": 87, "height": 16,
          "tooltip": "Line 1a: Total wages" },

        { "type": "rectangle", "x": 30,  "y": 30,
          "width": 552, "height": 18, "mode": "fill",
          "artifact": true, "artifactType": "layout",
          "drawOptions": { "fillColor": { "r": 0.0, "g": 0.2, "b": 0.5 } } },

        { "type": "text", "text": "SAMPLE",
          "x": 127, "y": 389,
          "artifact": true, "artifactType": "background",
          "options": { "fontRef": "title-font", "fontSize": 96,
                       "color": { "r": 0.85, "g": 0.1, "b": 0.1 },
                       "rotation": 20, "renderingMode": "stroke" } }
      ]
    }
  ]
}

Content Element Types

Type Key Properties Notes
texttext, x, y, optionsSingle line of text. options.rotation rotates around (x, y).
textBlocklines[], x, y, optionsMulti-line text block with automatic line spacing.
rectanglex, y, width, height, mode, drawOptionsmode: draw, fill, drawAndFill.
linex1, y1, x2, y2, drawOptionsStraight line segment.
circlecx, cy, r, mode, drawOptionsCircle by center and radius.
ellipsecx, cy, rx, ry, mode, drawOptionsEllipse with separate x/y radii.
polygonpoints[][], mode, drawOptionsClosed polygon from point list.
pathoperations[], render, drawOptionsLow-level BΓ©zier path (moveTo, lineTo, curveTo, closePath).
imageimageRef / source, x, y, width, heightsource accepts file path, URL, or Base64 data URI.
textFieldname, x, y, width, height, tooltip, defaultValue, multiline, password, maxLength, fontSize, readonly, requiredInteractive AcroForm text input.
checkboxFieldname, x, y, width, height, tooltipInteractive checkbox.
dropdownFieldname, x, y, width, height, options[], fontSize, tooltipCombo-box dropdown with static option list.
signatureFieldname, x, y, width, height, tooltipSignature widget annotation.

Text Options

Option Type Description
fontRefstringReferences a font id declared in the top-level fonts array.
fontSizenumberFont size in points.
colorstring or object"black", "white", {"r":0.8, "g":0.1, "b":0.1}, or {"gray":0.5}.
rotationnumberDegrees counter-clockwise. The rotation pivot is the text's (x, y) position.
renderingModestring"fill" (default), "stroke" (outline only β€” classic stamp look), "fillAndStroke", "invisible".
widthnumberText box width for alignment. Enables alignment option.
alignmentstring"left", "center", "right", "justify". Requires width.
leadingnumberLine spacing in points between lines. Default: fontSize × 1.2.

πŸ”– Adding a Stamp Watermark

The sample form-1040.json includes a diagonal SAMPLE stamp on every page. To add a stamp watermark to any page in your own JSON document, use artifact: true so it is correctly marked as a background artifact and excluded from the accessibility structure tree (ISO 14289-1 Β§7.1, Matterhorn 01-003). Use renderingMode: "stroke" for the classic hollow-text stamp look:

{
  "type": "text",
  "text": "DRAFT",
  "x": 127, "y": 389,
  "artifact": true,
  "artifactType": "background",
  "options": {
    "fontRef": "title-font",
    "fontSize": 96,
    "color": { "r": 0.85, "g": 0.1, "b": 0.1 },
    "rotation": 20,
    "renderingMode": "stroke"
  }
}

For a Letter-size page (coordinateOrigin: "topLeft") this positions the stamp centered at the page midpoint. Adjust x / y / fontSize for other page sizes. The rotation pivot is always the element's (x, y) point.

⚑ Easy Accessibility (New in v1.2.0)

Use "accessible": true at the root level to automatically enable PDF/UA-1 conformance, tagged PDF, document title display, and auto-tagging β€” no manual structureTree or structureId needed. The form-1040ea.json file above demonstrates this approach with the same Form 1040 content in dramatically simpler JSON.

{
  "accessible": true,
  "document": {
    "language": "en-US",
    "info": { "title": "Form 1040" }
  },
  "pages": [{ ... }]
}

See the ⚑ Easy Accessibility example for the complete guide.

β™Ώ Accessibility Notes

  • Easy mode: Set "accessible": true β€” auto-tags all text and images, enables PDF/UA-1. No structureTree or structureId required.
  • Manual mode: Set "tagged": true and supply a structureTree with structureId on each content element for full control over the tag hierarchy.
  • All form fields should have a tooltip value β€” this becomes the /TU entry required by Matterhorn checkpoint 28.
  • Background visual elements (rules, shading bands, watermarks) must be marked "artifact": true and must not have a structureId.
  • Set "language" at the document level to a valid BCP-47 tag (e.g. "en-US") β€” required by ISO 14289-1 Β§7.2.
  • Use PdfJsonRenderer.BuildDocument() + PdfAccessibilityChecker.Check() to validate the generated document programmatically before saving.