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
+38 -3
View File
@@ -3,15 +3,17 @@ using System.Windows;
using System.Windows.Media;
using PdfSharpCore.Drawing;
using PdfSharpCore.Pdf;
using MmdPdf;
namespace KillerPDF.Services
namespace MmdPdf.Services
{
// ============================================================
// Burn-to-document core - draws the overlay annotation layer
// and the stamp layer (page numbers / watermark) into a
// PdfDocument via XGraphics, in PDF-point space. Static and
// window-free by design (split out of Shell/Annotations.cs and
// Shell/Stamps.cs in the KillerUI refactor): the print flow
// Shell/Stamps.cs in the MmdPdfUI refactor): the print flow
// runs these on a background thread against a throwaway copy
// of the document, and being static means the compiler
// guarantees no live UI state is touched.
@@ -79,7 +81,7 @@ namespace KillerPDF.Services
private static int NormalizeRot(IReadOnlyDictionary<int, int>? rotations, int pageIdx, PdfPage page)
{
// KillerPDF-managed rotations live in the map after SaveTempAndReload strips them
// MmdPdf-managed rotations live in the map after SaveTempAndReload strips them
// from the working file. A newly opened PDF still carries its native /Rotate on the
// page, so use that value whenever the map has no entry for this page.
int r = rotations is not null && rotations.TryGetValue(pageIdx, out int stored)
@@ -128,6 +130,39 @@ namespace KillerPDF.Services
double sx = visW / renderW;
double sy = visH / renderH;
// MMD: an existing-text edit lays an opaque CoverAnnotation over the original
// run and draws the replacement on top - which left the original glyphs in the
// content stream, so text extraction still returned the old value. Strip them
// here, BEFORE appending our own content, so an edited figure is really gone.
{
var coverRects = new System.Collections.Generic.List<XRect>();
var visToPage = VisualToPageMatrix(rot, pwPt, phPt);
foreach (var cand in annots)
{
if (cand is not CoverAnnotation cov) continue;
var cr = cov.DrawRect();
double gx = cr.X * sx, gy = cr.Y * sy, gw = cr.Width * sx, gh = cr.Height * sy;
var corners = new[]
{
new XPoint(gx, gy), new XPoint(gx + gw, gy),
new XPoint(gx, gy + gh), new XPoint(gx + gw, gy + gh)
};
if (visToPage is XMatrix vm)
for (int ci = 0; ci < corners.Length; ci++) corners[ci] = vm.Transform(corners[ci]);
double minX = corners[0].X, maxX = corners[0].X, minY = corners[0].Y, maxY = corners[0].Y;
foreach (var pt in corners)
{
if (pt.X < minX) minX = pt.X;
if (pt.X > maxX) maxX = pt.X;
if (pt.Y < minY) minY = pt.Y;
if (pt.Y > maxY) maxY = pt.Y;
}
// XGraphics space is y-down from the top-left; PDF user space is y-up.
coverRects.Add(new XRect(minX, phPt - maxY, maxX - minX, maxY - minY));
}
if (coverRects.Count > 0) PdfRedactText.RemoveTextUnder(page, coverRects);
}
using var gfx = XGraphics.FromPdfPage(page, XGraphicsPdfPageOptions.Append);
// ...then turn the whole drawing back into the page's own frame, so every draw
// call below can keep working in visual coordinates exactly as it always has.