ststeiger / PdfSharpCore

Port of the PdfSharp library to .NET Core - largely removed GDI+ (only missing GetFontData - which can be replaced with freetype2)
Other
1.07k stars 239 forks source link

Writing a property sometimes causes PDF orientation to flip #326

Closed Hacnar closed 1 year ago

Hacnar commented 1 year ago

Sometimes, writing a property somehow causes the orientation of PDF to flip. If I remove the first property and write another one, the orientation flips back.

Here's example code, running on .NET 6 with PdfSharpCore 1.3.43:


namespace PdfSharpDemo
{
    static internal class PdfSharpUsage
    {
        static internal void WriteFirstProperty(string path)
        {
            var document = Open(path);
            var properties = document.Info.Elements;

            WriteProperty(properties, "FirstProperty", "valueOne");

            Close(document, path);
        }

        static internal void WriteSecondProperty(string path)
        {
            var document = Open(path);
            var properties = document.Info.Elements;
            properties?.Remove($"/FirstProperty");

            WriteProperty(properties, "SecondProperty", "valueTwo");

            Close(document, path);
        }

        static private PdfDocument Open(string path)
        {
            using var pdfStream = new FileStream(path, FileMode.Open, FileAccess.Read);
            return PdfSharpCore.Pdf.IO.PdfReader.Open(pdfStream, PdfSharpCore.Pdf.IO.PdfDocumentOpenMode.Modify);
        }

        static private void Close(PdfDocument document, string path)
        {
            document?.Save(path);
            document?.Close();
            document?.Dispose();
        }

        static private void WriteProperty(PdfDictionary.DictionaryElements properties, string name, string value)
        {
            if (properties != null)
            {
                if (properties.ContainsKey($"/{name}"))
                    properties.SetValue($"/{name}", new PdfString(value, PdfStringEncoding.Unicode));
                else
                    properties.Add($"/{name}", new PdfString(value, PdfStringEncoding.Unicode));
            }
        }
    }
}```

var file = @"C:\a.pdf"; PdfSharpUsage.WriteFirstProperty(file); Console.WriteLine("First property written. Press enter to continue."); Console.ReadKey(); PdfSharpUsage.WriteSecondProperty(file);



Here's an example file, which suffers from thsi issue.
[a.pdf](https://github.com/ststeiger/PdfSharpCore/files/10506818/a.pdf)
Hacnar commented 1 year ago

I spent a bit more time debugging this, and I found that the only difference in the resulting pdf files was /MediaBox property of PdfPage, which seemed to switch width and height every time the files has been saved to disk.

Hacnar commented 1 year ago

I've found the source of this issue. Some PDF files have unusual setting - rotation would suggest landscape orientation, but the page dimensions suggest otherwise. When I initialize PdfPage._orientation with values in /MediaBox taken into consideration, things work fine. I suspect Adobe and other PDF viewers approach orientation similarly, because they reported Portrait when PdfSharpCore initialized _orientation to Landscape.

I will create PR with my proposed changes.

EDIT: here's pull request

Hacnar commented 1 year ago

The PR has been merged, and I've tested the latest nuget package (1.3.47). It works fine now, so I'm closing this issue.