feat: rebrand to MMD PDF, single corporate theme, and remove original text under an edit

- Services/PdfRedactText.cs: strip text whose origin falls inside a CoverAnnotation
  from the page content stream at save time, hooked into PdfBurn.DrawAnnotationsIntoDoc.
  Fixes edited values staying recoverable by text extraction.
- Themes/MMD.xaml replaces all thirteen themes; picker and accent strip removed; no dark mode.
- Rename KillerPDF -> MMD PDF across code, resources, packaging and locale strings; new icon.
- Remove the upstream author credit and the in-app install button.
This commit is contained in:
2026-08-27 07:37:09 +02:00
parent 532485a830
commit 6610acfa44
230 changed files with 9362 additions and 11508 deletions
+4 -4
View File
@@ -4,12 +4,12 @@
validation outcome changed between the two runs.
.DESCRIPTION
Used to verify that resaving PDFs through KillerPDF does not degrade
Used to verify that resaving PDFs through MmdPdf does not degrade
standards conformance. Workflow:
1. Baseline the corpus:
verapdf --recurse --format json C:\pdf-corpus > baseline.json
2. Resave every corpus file through KillerPDF into a mirror folder,
2. Resave every corpus file through MmdPdf into a mirror folder,
preserving relative paths (see --batch-resave).
3. Validate the resaved tree:
verapdf --recurse --format json C:\pdf-corpus-resaved > after.json
@@ -29,7 +29,7 @@
.NOTES
Compatible with Windows PowerShell 5.1 and PowerShell 7.
Part of the KillerPDF validation harness (validation/).
Part of the MmdPdf validation harness (validation/).
#>
[CmdletBinding()]
param(
@@ -233,7 +233,7 @@ if ($CsvOut) {
}
if ($regressionCount -gt 0) {
Write-Host 'RESULT: FAIL - KillerPDF resave introduced regressions.' -ForegroundColor Red
Write-Host 'RESULT: FAIL - MmdPdf resave introduced regressions.' -ForegroundColor Red
exit 1
} else {
Write-Host 'RESULT: PASS - no conformance regressions introduced.' -ForegroundColor Green
+2 -2
View File
@@ -5,7 +5,7 @@
.DESCRIPTION
The second half of the release validation (Compare-VeraPDF.ps1 is the first). Reads the
resave log written by `KillerPDF.exe --batch-resave` and checks only the rows marked OK -
resave log written by `MmdPdf.exe --batch-resave` and checks only the rows marked OK -
skipped files were never written and have nothing to compare.
qpdf exit codes: 0 = clean, 2 = errors, 3 = warnings only. "Worsened" is any pair whose
@@ -18,7 +18,7 @@
.NOTES
Compatible with Windows PowerShell 5.1 and PowerShell 7.
Part of the KillerPDF validation harness (validation/).
Part of the MmdPdf validation harness (validation/).
#>
[CmdletBinding()]
param(
+15 -15
View File
@@ -1,19 +1,19 @@
# Standards-conformance validation results - KillerPDF 1.7.5
# Standards-conformance validation results - MmdPdf 1.7.5
veraPDF run date: 2026-08-22, against the 1.7.5 release build. This small maintenance release
changes live annotation rotation behavior, mouse-wheel navigation, shortcuts, and localization,
without changing the PDF serializer. The standard open/save pipeline was nevertheless run fresh
across the complete corpus because every KillerPDF release must independently meet the same
across the complete corpus because every MmdPdf release must independently meet the same
zero-regression bar. The run reproduces every established count exactly: 2,236 successful resaves, 671 refusals
matching the SKIP rows one for one, 63 improvements, and the same single documented PDF/A-4
header case as the only flagged saved file. The qpdf sweep also reproduces its table exactly:
2,032 clean both sides, 195 improved, 9 kept preexisting warnings, 0 worsened.
Question under test: does saving a PDF through KillerPDF degrade its
Question under test: does saving a PDF through MmdPdf degrade its
standards conformance? Every file in a 2,907-file public corpus was validated, resaved through
KillerPDF's standard open/save pipeline, and validated again.
MmdPdf's standard open/save pipeline, and validated again.
Result: **Zero** conformance regressions across every file KillerPDF will save, with one documented engine limitation
Result: **Zero** conformance regressions across every file MmdPdf will save, with one documented engine limitation
(PDF/A-4's PDF 2.0 header). **63 files came out more conformant than they went in.**
## Tools
@@ -22,7 +22,7 @@ Result: **Zero** conformance regressions across every file KillerPDF will save,
|---|---|---|
| veraPDF | 1.30.2 | PDF/A + PDF/UA validation (the industry reference validator) |
| qpdf | 12.3.2 | Structural check (`--check` exit codes) |
| KillerPDF | 1.7.5 | `--batch-resave` through the standard open/save pipeline |
| MmdPdf | 1.7.5 | `--batch-resave` through the standard open/save pipeline |
| Compare-VeraPDF.ps1 | this folder | Diffs the two veraPDF reports file by file |
| QpdfSweep.ps1 | this folder | Structural before/after sweep (`qpdf --check` exit codes) |
@@ -36,7 +36,7 @@ standard, so any structural damage a resave introduces shows up as a new failed
## Method
1. Validate the pristine corpus: `verapdf --recurse --format json <corpus> > baseline.json`
2. Resave every file through KillerPDF: `KillerPDF.exe --batch-resave <corpus> <resaved> --log resave.csv`
2. Resave every file through MmdPdf: `MmdPdf.exe --batch-resave <corpus> <resaved> --log resave.csv`
3. Validate the resaved tree the same way into `after.json`
4. `Compare-VeraPDF.ps1` matches files by relative path and flags any file that fails a rule
after the resave that it did not fail before
@@ -56,7 +56,7 @@ standard, so any structural damage a resave introduces shows up as a new failed
| Improved (fails fewer rules than before) | 4 |
| Regressed | 1 (the documented PDF/A-4 header case below) |
The 671 skips are encrypted files and files damaged beyond parsing. KillerPDF refuses to
The 671 skips are encrypted files and files damaged beyond parsing. MmdPdf refuses to
resave what it cannot fully read rather than risk writing a damaged file; each one is a SKIP
row in `resave.csv`, and all 671 files absent from the after-report cross-check exactly
against those SKIP rows. No file went missing for any other reason.
@@ -67,10 +67,10 @@ through a clean serializer repairs that class of defect.
## The one known limitation: PDF/A-4
ISO 19005-4 (PDF/A-4) is built on PDF 2.0 and requires a `%PDF-2.0` header. KillerPDF's write
ISO 19005-4 (PDF/A-4) is built on PDF 2.0 and requires a `%PDF-2.0` header. MmdPdf's write
engine serializes PDF 1.7, so the single PDF/A-4 corpus file gains ISO 19005-4:2020 clause
6.1.3 tests 4 and 5 after a resave. This is a version-marker limitation, not structural
damage: qpdf reports the resaved file clean. PDF 2.0 serialization is future work; KillerPDF
damage: qpdf reports the resaved file clean. PDF 2.0 serialization is future work; MmdPdf
does not claim PDF/A-4 output.
## qpdf structural sweep
@@ -89,7 +89,7 @@ No file's structural health got worse; 195 files with qpdf warnings came out cle
## What had to be fixed to get here
The write engine is PdfSharpCore 1.3.67 (MIT), vendored under `third_party/PdfSharpCore/`
with six patches, each marked `KillerPDF patch` in the source:
with six patches, each marked `MmdPdf patch` in the source:
1. **No Producer/Creator stamping** into an imported document's Info dictionary. PDF/A
(ISO 19005-1 clause 6.7.3) requires the Info dictionary to stay equivalent to the XMP
@@ -106,7 +106,7 @@ with six patches, each marked `KillerPDF patch` in the source:
leaked into indirect boolean objects as `True`, which is not a valid PDF token
(ISO 32000-1 clause 7.3.2). This broke `/MarkInfo /Marked` in PDF/UA files.
On top of the library patches, every save runs three scrubs in KillerPDF itself:
On top of the library patches, every save runs three scrubs in MmdPdf itself:
- **Dangling /Outlines removal** - reading `doc.Outlines` plants an empty outline dictionary
that becomes a dangling reference (the 1.6.3 corruption bug).
@@ -124,7 +124,7 @@ corpora). On a tree containing the corpus:
```
verapdf --recurse --format json C:\pdf-corpus > baseline.json
Start-Process -Wait KillerPDF.exe -ArgumentList '--batch-resave','C:\pdf-corpus','C:\pdf-corpus-resaved','--log','resave.csv'
Start-Process -Wait MmdPdf.exe -ArgumentList '--batch-resave','C:\pdf-corpus','C:\pdf-corpus-resaved','--log','resave.csv'
verapdf --recurse --format json C:\pdf-corpus-resaved > after.json
.\Compare-VeraPDF.ps1 -Baseline baseline.json -After after.json `
-BaselineRoot C:\pdf-corpus -AfterRoot C:\pdf-corpus-resaved -CsvOut compare.csv
@@ -132,13 +132,13 @@ verapdf --recurse --format json C:\pdf-corpus-resaved > after.json
-ResaveLog resave.csv -CsvOut qpdf-results.csv
```
**The resave step must be `Start-Process -Wait`** (or otherwise blocked on): KillerPDF.exe is
**The resave step must be `Start-Process -Wait`** (or otherwise blocked on): MmdPdf.exe is
a GUI-subsystem binary, so a bare invocation returns immediately and the after-scan then
validates a half-written tree - every not-yet-written file shows up as MISSING_AFTER (this
burned the 1.7.0 run, twice).
The compare script counts every MISSING_AFTER as a regression by design, so a run with skips
exits 1 even when clean. The release bar is: every MISSING_AFTER row cross-checks against a
SKIP row in `resave.csv` (encrypted/unparseable files KillerPDF refuses to touch), and the
SKIP row in `resave.csv` (encrypted/unparseable files MmdPdf refuses to touch), and the
only rule-level change is the documented PDF/A-4 header case. Anything beyond that is a real
regression.