Skip to content

Majorsilence.Pdf#281

Merged
majorsilence merged 22 commits into
mainfrom
dev
Jun 19, 2026
Merged

Majorsilence.Pdf#281
majorsilence merged 22 commits into
mainfrom
dev

Conversation

@majorsilence

@majorsilence majorsilence commented Jun 17, 2026

Copy link
Copy Markdown
Owner

This pull request introduces a comprehensive test suite for the Majorsilence.Pdf library and adds example and test project scaffolding. The main focus is on ensuring correctness and robustness of core PDF features such as color handling, page sizing, and font registry management, as well as providing the necessary infrastructure for running and organizing these tests.

Test coverage improvements:

  • Added PdfColorTests to verify construction, parsing, equality, and string representation of PdfColor, including hex parsing and named color values.
  • Added PageSizeTests to check correctness of PdfPageSize and PageSizes (dimensions, orientation, and series relationships).
  • Added FontRegistryTests to thoroughly test FontRegistry and FontSource, including registration, resolution, fallback mechanisms, directory scanning, and integration with PDF rendering and measurement.

Project and solution scaffolding:

  • Added Majorsilence.Pdf.Tests.csproj with references to required packages and the main project, targeting .NET 8.0 and 10.0, and enabled nullable reference types.
  • Added example project MajorsilencePdfExample.csproj and corresponding solution file MajorsilencePdfExample.slnx for demonstration purposes. [1] [2]

Introduce a native PDF 1.4 writer and a raw PDF renderer.

- Add PdfDocumentWriter: builds PDF files (fonts, embedded TrueType, images, annotations, metadata) and writes cross-reference/trailer; uses SharpZipLib for Flate compression.
- Add TrueTypeFont: minimal TrueType/OpenType parser to extract metrics, glyph widths and cmap for embedding CIDFont Type2 and ToUnicode CMap.
- Add RenderPdf_Raw: new renderer that emits PDF content streams (text, shapes, images, annotations) using PdfDocumentWriter and resolves/embeds fonts via TrueTypeFont; includes platform font-folder heuristics and image handling (JPEG and raw RGB).
- Register new output type RenderPdf_Raw in ProcessReport enum.
- Add tests scaffold ReportTests/RenderPdf_RawTests.cs.

This enables an internal PDF output option without relying on a third-party PDF library and supports full font embedding for TrueType/OpenType fonts, basic image formats, and annotations.
Create a new Majorsilence.Pdf library and move PDF writer implementation into it. Adds Majorsilence.Pdf.csproj (netstandard2.0, SharpZipLib, packable) and registers the project in the solution and RdlEngine project references. Rename namespaces to Majorsilence.Pdf and relocate PdfDocumentWriter and TrueTypeFont files. Make types and members public, add nullable annotations, tighten APIs (SetMetadata, AddPage, GetOrAdd* methods, Write, Fmt, EncodeText, etc.), and clean up encoding/stream helpers and object serialization formatting. Also update references/usings in RenderPdf_Raw to use the new project. The change extracts a zero-dependency PDF generator into a reusable package and prepares it for NuGet packaging.
Copilot AI review requested due to automatic review settings June 17, 2026 22:24

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a new PDF rendering path (RenderPdf_Raw) that generates PDF output without iTextSharp by introducing a new Majorsilence.Pdf library and wiring it into the RDL engine’s render switch, along with a basic NUnit test to exercise the new output type.

Changes:

  • Add OutputPresentationType.RenderPdf_Raw and route it through Report.RunRender.
  • Implement a new raw PDF renderer (RenderPdf_Raw) backed by a new Majorsilence.Pdf writer and TTF parser.
  • Add a new NUnit test that renders several sample reports using the new raw PDF output.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
ReportTests/RenderPdf_RawTests.cs Adds an integration-style test that renders reports to the new raw PDF output.
RdlEngine/Runtime/Report.cs Wires the new RenderPdf_Raw output type into the rendering dispatch.
RdlEngine/Render/RenderPdf_Raw.cs Implements the new PDF renderer that writes PDF content/resources directly.
RdlEngine/Render/ProcessReport.cs Extends OutputPresentationType with RenderPdf_Raw.
RdlEngine/Majorsilence.Reporting.RdlEngine.csproj Adds a project reference to the new Majorsilence.Pdf library.
MajorsilenceReporting.sln Adds the Majorsilence.Pdf project to the solution.
Majorsilence.Pdf/TrueTypeFont.cs Introduces a minimal TrueType/OpenType parser for metrics and cmap mappings.
Majorsilence.Pdf/PdfDocumentWriter.cs Introduces a PDF 1.4 writer supporting fonts, images, annotations, and metadata.
Majorsilence.Pdf/Majorsilence.Pdf.csproj Adds the new PDF library project (netstandard2.0) with SharpZipLib dependency.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread RdlEngine/Render/RenderPdf_Raw.cs Outdated
Comment thread RdlEngine/Render/RenderPdf_Raw.cs Outdated
Comment thread Majorsilence.Pdf/PdfDocumentWriter.cs Outdated
Comment thread RdlEngine/Render/RenderPdf_Raw.cs Outdated
using var sg = new OneFileStreamGen(outFile, true);
await rap.RunRender(sg, OutputPresentationType.RenderPdf_Raw);

Assert.That(File.Exists(outFile), "PDF output file was not created");
Introduce a new Majorsilence.Pdf library with core PDF functionality: PdfDocument, PdfCanvas, PdfColor, TextStyle/ShapeStyle/StrokeStyle/LineStyle, PageSizes, TrueTypeFont improvements, font registry and internal helpers (FontCache, PdfSerializer). Add a comprehensive test suite (Majorsilence.Pdf.Tests) exercising font registry, rendering and fallback behavior, and include an Examples/MajorsilencePdfExample console app demonstrating features and bundled fonts. Update solution files and adjust related projects (modified TrueTypeFont and RdlEngine render integration); remove PdfDocumentWriter (deleted). Tests use PdfPig for PDF validation and assume bundled/system fonts where applicable.
Build and attach a FontRegistry to the PDF document and overhaul font resolution. Introduces BuildFontRegistry, TryAddFamily and MapFaceToRegistryFamily to register bundled and system fonts (OS-specific handling) and select metric-compatible substitutions and fallbacks. ResolveFont now prefers the registry for embedding/variants and falls back to standard Type-1 families; NormalizeFace mappings updated (e.g. Times New Roman) and Symbol/ZapfDingbats handled as Type-1. Also small API/formatting cleanups: avoid copying JPEG image buffers, inline style construction for drawing calls, early returns and minor whitespace/structure refactors for readability.
Rename the OutputPresentationType enum member RenderPdf_Raw to RenderPdf_Majorsilence and update all usages accordingly. Adjusted the switch case in Report.RunRender to match the new enum value and updated the RenderPdf_RawTests to call RunRender with OutputPresentationType.RenderPdf_Majorsilence. No behavior changes intended; this is a symbolic rename across ProcessReport.cs, Report.cs, and the test.
Add horizontal alignment handling in PdfCanvas.DrawText so right- and center-aligned text is positioned correctly by measuring text width and adjusting x. Increase spacing before the "Total Due" line in the example (y offset from 4 to 14) to improve layout. Also include minor fixes and formatting cleanups across PdfCanvas (decoration line calculation, ellipse Bezier formatting, dash default formatting, and several whitespace/formatting refactors) to improve readability and maintain consistent code style.
Switch PDF compression to System.IO.Compression and multi-target .NET 6 and netstandard2.0. PdfSerializer now uses ZLibStream on NET6 (which handles zlib header + Adler-32) and falls back to writing the zlib envelope (0x78 0x9C), using DeflateStream and a manual Adler32 implementation for netstandard2.0. Removed SharpZipLib usings and package reference, and updated the project to target netstandard2.0;net6.0.
Track glyph IDs used on a page and produce subsetted TrueType fonts to reduce output size. FontResource now holds a UsedGlyphs set; PdfCanvas passes that set when encoding glyph IDs so EncodeGlyphIds records used glyphs. PdfSerializer.BuildTtfFontObjs filters the ToUnicode CMap and /W width array to only include used glyphs, and writes a subsetted FontFile2 stream (falling back to the full font if no subsetting is possible). TrueTypeFont.Subset implements glyph subsetting: it parses loca/glyf/head, includes .notdef and composite components, builds new loca/glyf/head tables (long format), reassembles the font tables and fixes checksum. Helper routines for writing binary tables and checksums were added.
Add a new Unicode/UTF-8 example to the sample program (UnicodeExample) and register it in the example runner. The example demonstrates Latin Extended, Greek, Cyrillic, emoji and CJK rendering and shows fallback behavior when glyphs are missing. Also add comprehensive NUnit tests (Majorsilence.Pdf.Tests/UnicodeRenderingTests.cs) covering accented Latin, Greek, Cyrillic, mixed-script fallback segmentation, emoji (surrogates), optional system CJK/emoji fonts, subsetting behavior, measurement of non-Latin text, and ensuring RTL/Arabic input does not crash. Includes a small formatting/whitespace tweak in the sample program.
@majorsilence majorsilence changed the title Dev Majorsilence.Pdf Jun 18, 2026
@majorsilence
majorsilence merged commit 38b8fec into main Jun 19, 2026
9 checks passed
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.

2 participants