User-facing documentation for Papercraft XML templates and the X39.Solutions.PdfTemplate compatibility bridge.
| Previous: Migration to Papercraft | Manual home |
This page is the maintainer plan for the additive migration from
X39.Solutions.PdfTemplate to Papercraft. It describes the current package split and the
remaining release work needed before the Papercraft packages are the primary distribution path.
source/X39.Solutions.PdfTemplate. It preserves
AddPdfTemplateService() and legacy type identities while referencing the Papercraft projects.source/X39.Solutions.Papercraft.Core now contains renderer-neutral contracts and the current shared
runtime: XML parsing, template data, functions, transformers, control registration, built-in
controls, deferred canvas/display-list primitives, render targets, diagnostics, capabilities,
PapercraftGenerator, PapercraftRenderer, PapercraftInstrumentation, PapercraftServiceBuilder, AddPapercraftCore()
and related options.
It must stay free of a SkiaSharp package reference.source/X39.Solutions.Papercraft.Rendering.SkiaSharp owns the SkiaSharp-backed runtime: text
measurement, paint cache, Skia conversions, SkiaSharpRenderBackend,
SkiaSharpDisplayListRenderer and AddPapercraftSkiaSharpRenderer().source/X39.Solutions.Papercraft is the default facade package project. It references core plus the
SkiaSharp renderer, exposes AddPapercraft(), and forwards the application-facing Papercraft
types from core.GenerateBitmapsAsync(...) compatibility path.| Package | Target responsibility |
|---|---|
X39.Solutions.Papercraft.Core |
Renderer-neutral contracts, parsing, template data, layout/control abstractions, validation, diagnostics and display-list primitives. No SkiaSharp dependency. |
X39.Solutions.Papercraft.Rendering.SkiaSharp |
SkiaSharp renderer, PDF/raster output, immediate drawing, image decoding, text measurement, font resolution, paint/cache services and Skia compatibility adapters. |
X39.Solutions.Papercraft |
Batteries-included facade for normal application use. Depends on core and the default SkiaSharp renderer. |
X39.Solutions.Papercraft.OpenTelemetry |
Optional host/OpenTelemetry integration that registers Papercraft’s core ActivitySource without adding hosting dependencies to Core. |
X39.Solutions.PdfTemplate |
Compatibility bridge for existing users. Keeps old service registration, namespaces, templates and common extension points working while forwarding to Papercraft packages. |
Core should define what a renderer can do; renderer packages should define how output is produced. The facade should remain small and opinionated. The compatibility bridge should eventually contain only wrappers, type-forwarders and compatibility documentation.
AddPdfTemplateService(), Generator, DocumentOptions, custom controls and existing
builder methods working through the bridge.AddPapercraft() and PapercraftRenderer as the recommended new render entry point, without
forcing applications to change in the same release.SKBitmap, SKCanvas, SKPaint or Skia native asset behavior in the
SkiaSharp renderer or compatibility bridge, not in core.Recommended application path:
services.AddPapercraft();
var renderer = serviceProvider.GetRequiredService<PapercraftRenderer>();
await renderer.GeneratePdfAsync(output, reader, CultureInfo.CurrentUICulture);
Renderer-neutral setup path:
services.AddPapercraftCore();
services.AddPapercraftSkiaSharpRenderer();
Compatibility path:
services.AddPdfTemplateService();
var generator = serviceProvider.GetRequiredService<Generator>();
await generator.GeneratePdfAsync(output, reader, CultureInfo.CurrentUICulture);
| Existing API | Papercraft API |
|---|---|
AddPdfTemplateService() |
AddPapercraft() |
PdfTemplateServiceBuilder |
PapercraftServiceBuilder |
Generator.GeneratePdfAsync(...) |
PapercraftRenderer.GeneratePdfAsync(...) |
DocumentOptions |
PapercraftRenderOptions.DocumentOptions |
| implicit default renderer | backend selection by PapercraftRenderOptions.BackendId or target capability |
PapercraftGenerator generates backend-neutral PapercraftDocument pages. PapercraftRenderer
is the facade for validation, backend selection and rendering. RenderTarget, RenderOutput,
RasterPageRenderOutput, PapercraftRenderOptions, PapercraftDocument and PapercraftPage
are the stable contracts between callers, the generator and backends.
Current core-owned renderer-neutral contract inventory:
IPapercraftRenderBackend, PapercraftDocument, PapercraftPage, PapercraftRenderOptions,
PapercraftInstrumentation, PapercraftMediaTypes, RenderTarget, RenderOutput, RasterPageInfo,
RasterPageRenderOutput, RendererOutputKind, RendererSupportLevel, RendererCapabilities,
RendererFeatures, RenderFeatureUse, RenderDiagnosticCodes, RenderDiagnostic,
RenderValidationResult, RenderValidationException and TemplateLocation.
RendererCapabilities is the canonical renderer descriptor. It carries renderer id, display name,
output kinds, media types, feature support levels and notes.RendererFeatures names capabilities such as PDF output, raster output, multipage output, text,
images, clipping, transparency, fonts, color and absolute positioning.RendererSupportLevel distinguishes supported, degraded and unsupported features.RenderFeatureUse records renderer-relevant template feature use; RenderDiagnostic and
RenderValidationResult report stable PAPERCRAFT### codes, feature ids, support level,
message, backend limitation and optional template location.PapercraftRenderOptions.TreatDegradedAsUnsupported is enabled.RenderRasterPagesAsync(...).X39.Solutions.Papercraft.Core has no SkiaSharp reference and that Skia-specific APIs live in
X39.Solutions.Papercraft.Rendering.SkiaSharp or the bridge.X39.Solutions.Papercraft.OpenTelemetry, not Core.AddPapercraftCore(), AddPapercraftSkiaSharpRenderer(), AddPapercraft() and
AddPdfTemplateService() registration paths.GenerateBitmapsAsync(...) remains SkiaSharp-specific and should stay on the compatibility path
while new code uses renderer-neutral raster page output.| Phase | Status | Acceptance criteria |
|---|---|---|
| 1. Compatibility facade | Verified locally | AddPdfTemplateService() and AddPapercraft() both work, existing templates do not change, and docs show the additive migration path. |
| 2. Core/runtime split | Verified locally | Core owns contracts plus shared parsing/runtime services and builds without a SkiaSharp package dependency. |
| 3. Skia renderer extraction | Verified locally | Skia canvas, text, image, paint, bitmap and renderer registration live in X39.Solutions.Papercraft.Rendering.SkiaSharp. |
| 4. Facade/package consumption | Verified locally | X39.Solutions.Papercraft consumes core plus SkiaSharp renderer, exposes the default setup path and passes package-consumption tests. |
| 5. Diagnostics hardening | Verified locally | Validation reports stable diagnostics for unsupported and degraded targets/features before render output begins. |
| 6. Compatibility bridge cleanup | In progress | X39.Solutions.PdfTemplate mostly acts as old entry points, wrappers, type-forwarders and package metadata; legacy namespace debt remains intentionally additive. |
| 7. Migration release | In progress | Package readmes and manual pages agree, local packages pack, package-consumption tests pass and PDF/PNG/raster-page parity smoke checks pass; publishing and final obsolete guidance remain release work. |
| Previous: Migration to Papercraft | Manual home |