Repository navigation
Fixes and improvements (incl. rich tables borders) #416
Description
Hello! Sorry to see this project step out of MIT license.
I had been carrying a set of PDFsharp and MigraDoc changes in my PDFsharp fork. I split the smaller fixes into focused PRs with regression tests so they can be reviewed and cherry-picked individually. The links below are a shortlist, grouped by the kind of change. Some later PRs in the fork are stacked, so their base branch and preceding commits should be checked before cherry-picking. I am sharing them here in case they are useful. The table borders are probably an interesting feature to integrate, and several correctness fixes are probably to.
Many of the other hooks are for customization - I am converting docx to pdf (https://github.com/gaspardpetit/Docxport.Net) and PDFsharp got me 80% there. There were still many cases where I needed to fine tune spacing, word alignment, etc. to mirror a Word pdf export - and this is now mostly achieved.
Thanks for the work over the years!
Correctness
- Stop hexadecimal string scanning at EOF. An unterminated
<...string can otherwise leave the lexer scanning indefinitely. This came from jafin/PdfSharpCore #70 and addresses PDFsharp issue #266. - Save a modified PDF back to its input stream. Replaces the original stream contents instead of appending a second PDF; failed serialization leaves the input intact. Adapted from jafin/PdfSharpCore #18, which addressed PdfSharpCore issue #422.
- Keep named destinations attached to imported pages. Stores the final page reference after object numbering, so the destination still resolves after save and reopen. First integrated in Pdfxport #2.
- Encode supplementary Unicode characters correctly in ToUnicode maps. Writes UTF-16BE surrogate pairs so extracted text retains characters above U+FFFF. Present in earlier Pdfxport history.
- Preserve blank-glyph TrueType subsets. Keeps a valid
glyftable when every included glyph is blank. Originated in PdfPinata; integrated in Pdfxport #8. - Write the Adler-32 trailer for Flate streams. Completes the zlib wrapper expected by readers that validate its checksum. Originated in petergolde/PDFsharp; integrated in Pdfxport #29.
- Import top-down BMPs in their stored row order. Prevents images with a negative BMP height from being inverted. Integrated in Pdfxport #37.
- Set an imported PDF's modification date when saving. Opening a document no longer changes its in-memory date; an explicitly selected date remains respected. Based on PdfSharpCore #496 and its issue #365.
Useful configuration hooks
These are MigraDoc rendering hooks with unchanged default behavior when unused:
- Inspect formatted table layout. Exposes typed cell positions and spans after formatting. Integrated in Pdfxport #52.
- Adjust underline geometry. Lets callers supply measured underline position and thickness. Integrated in Pdfxport #43.
- Adjust paragraph word width during layout. Allows a per-paragraph callback to tune line breaks without changing painted glyph advances. Integrated in Pdfxport #21.
- Adjust tab leader layout. Exposes typed spacing and inset settings for leader characters. Integrated in Pdfxport #42.
Improvements
- Resolve requested faces in Windows font collections. Allows selected faces in installed TrueType collections to be used instead of falling back. Adapted from petergolde's earlier work and follow-up; integrated in Pdfxport #32 and #34.
- Render richer table borders and resolve junctions. Adds compound, patterned, and shaded borders with explicit edge and junction geometry, including mixed styles. This is a cohesive larger change developed through Pdfxport #38, #39, #64, and #65. It is best reviewed as a feature rather than a small independent fix, and its stack dependencies need to be included.
I checked the currently open PDFsharp PRs and left out overlapping work, including nested composite glyph closure (#349), fully merged table rows (#359), StartFigure (#342), miter limits (#341), and font-cache concurrency (#382). I also left out header/footer render information while #355 is pending. If any shortlist item is already covered elsewhere, please point me to it and I will remove it.
Activity
gaspardpetit commentedon Oct 22, 2026
Adding another one to the list:
/Descent is written from the internal Descender without negating it. The internal metric calculation in OpenTypeFontDescriptor.cs stores descent as a positive magnitude for normal fonts, while the PDF descriptor itself requires a negative value.
Fixed in gaspardpetit#77