PDFsharp & MigraDoc Foundation

PDFsharp - A .NET library for processing PDF & MigraDoc Foundation - Creating documents on the fly
It is currently Thu Mar 28, 2024 6:16 pm

All times are UTC


Forum rules


Please read this before posting on this forum: Forum Rules



Post new topic Reply to topic  [ 13 posts ] 
Author Message
PostPosted: Thu Dec 17, 2015 2:42 pm 
Offline

Joined: Thu Dec 17, 2015 2:20 pm
Posts: 4
Hello,
I found a bug with landscape page.
Each time I load and save a landscape page, the MediaBox get rotated by 90 degree.

Example:
Original landscape PDF
Attachment:
Page original.jpg
Page original.jpg [ 25.26 KiB | Viewed 33586 times ]


Here is the PDF just opened and re-saved, as you can see the boundary are turned by 90 degree.
Attachment:
Page 1st save.jpg
Page 1st save.jpg [ 19.6 KiB | Viewed 33586 times ]


If I open the resaved file, and save it again, then the media box get turned again.

To me this seem a bug in PdfSharp, is it possible to fix it?

The code to get this bug is very simple:

Code:
     'read the original pdf
        pdfDoc = PdfReader.Open(currentPath & "\Page Landscape.pdf")
        'save the pdf, this will mess up the media-box
        pdfDoc.Save(currentPath & "\Page Landscape - 1st save, WRONG.pdf")


I've attached the sourcecode of a working example.
Attachment:
BugPdfSharpLandscape Source.zip [30.42 KiB]
Downloaded 2000 times



I also put together some code that seem to fix this bug... it works in some case, but I don't know if it's the correct way to fix the issue.
Also, I don't know if the issue happen during the file loading, or during the file saving.



Here is my quick and dirty fix, that works in some situation, but fail in others... (landscape turned by 90degree, it works, landscape turned by 270 degree, it fail... it need more testing, or just a fix in the library)
Code:
    Public Shared Sub FixLandscapePages(pdfDoc As PdfSharp.Pdf.PdfDocument)

        'landscape pages fix
        'the fix must be the last action executed against the page, and it must be done exactly one time for each page

        For Each page As PdfPage In pdfDoc.Pages
            If page.MediaBox.Width <> page.Width.Point Or page.MediaBox.Height <> page.Height.Point Then
                page.MediaBox = New PdfRectangle(New XPoint(0, 0), New XPoint(page.Width.Point, page.Height.Point))
            End If

        Next

    End Sub



Thanks,
Max


Top
 Profile  
Reply with quote  
PostPosted: Sat Dec 19, 2015 8:57 pm 
Offline
PDFsharp Expert
User avatar

Joined: Sat Mar 14, 2015 10:15 am
Posts: 909
Location: CCAA
Hi, Max,

Yes, this bug should be fixed in the library.

I made an experimental change in class PdfPage.cs:
Code:
internal PdfPage(PdfDictionary dict)
    : base(dict)
{
    // Set Orientation depending on /Rotate.
    //int rotate = Elements.GetInteger(InheritablePageKeys.Rotate);
    //if (Math.Abs((rotate / 90)) % 2 == 1)
    //    _orientation = PageOrientation.Landscape;
}


I don't know if this works in all cases, but it works with your test code.

PDFsharp source is available on CodePlex, SourceForge, GitHub - in case you want to test it.

_________________
Best regards
Thomas
(Freelance Software Developer with several years of MigraDoc/PDFsharp experience)


Top
 Profile  
Reply with quote  
PostPosted: Mon Dec 21, 2015 2:25 pm 
Offline

Joined: Thu Dec 17, 2015 2:20 pm
Posts: 4
TH-Soft wrote:
Hi, Max,

Yes, this bug should be fixed in the library.

I made an experimental change in class PdfPage.cs:
Code:
internal PdfPage(PdfDictionary dict)
    : base(dict)
{
    // Set Orientation depending on /Rotate.
    //int rotate = Elements.GetInteger(InheritablePageKeys.Rotate);
    //if (Math.Abs((rotate / 90)) % 2 == 1)
    //    _orientation = PageOrientation.Landscape;
}


I don't know if this works in all cases, but it works with your test code.

PDFsharp source is available on CodePlex, SourceForge, GitHub - in case you want to test it.


Thank you for looking into my issue.
Now I'm trying the modified code (I'm using the source version 1.32).
I'll let you know if I have other issues.


Top
 Profile  
Reply with quote  
PostPosted: Tue Dec 22, 2015 3:12 pm 
Offline

Joined: Thu Dec 17, 2015 2:20 pm
Posts: 4
Hello
after much testing, I've come up with different code to try to fix this bug:

Modification 1
Code:
internal PdfPage(PdfDictionary dict)
  : base(dict)
{
   //// Set Orientation depending on / Rotate
   //int rotate = Elements.GetInteger(PdfPage.Keys.Rotate);
   //if (Math.Abs((rotate / 90)) % 2 == 1)
   //    this.orientation = PageOrientation.Landscape;

   bool dimensionsLooksLandscape = false;
   bool rotationLooksLandscape = false;

    //check if the rotation seem to be landscape (this is only true if the starting page was portrait, whic IS NOT always the case)
   int rotate = Elements.GetInteger(PdfPage.Keys.Rotate);
   if (Math.Abs((rotate / 90)) % 2 == 1)
      rotationLooksLandscape = true;

   //check if the page dimensions seem to be from a landscape page (which IS the case if the pdf document is a scan of a landscape A4)
   if (this.Width > this.Height)
      dimensionsLooksLandscape = true;

   //now, if the PDF was a landscape A4 (so dimensionsLooksLandscape == true) and was rotated by 270° (so rotationLooksLandscape == true) then it will looks portrait
   if (dimensionsLooksLandscape ^ rotationLooksLandscape)
      this.orientation = PageOrientation.Landscape;
}



Modification 2 (I've only commented out some code, my modifications are preceded by //-----------------------// )

Code:
        internal override void WriteObject(PdfWriter writer)
        {
            // HACK: temporarily flip media box if Landscape
            PdfRectangle mediaBox = MediaBox;
            // TODO: Take /Rotate into account



            //-----------------------//Commented by MaxDna
            //-----------------------//if (orientation == PageOrientation.Landscape)
            //-----------------------//    MediaBox = new PdfRectangle(mediaBox.X1, mediaBox.Y1, mediaBox.Y2, mediaBox.X2);



            //#warning THHO4STLA: warum nicht new PdfRectangle(mediaBox.Y1, mediaBox.X1, mediaBox.Y2, mediaBox.X2)? - siehe auch Orientation
            //#warning THHO4STLA: CropBox, BleedBox etc. auch drehen?

#if true
            // Add transparency group to prevent rendering problems of Adobe viewer
            this.transparencyUsed = true; // TODO: check XObjects
            if (this.transparencyUsed && !Elements.ContainsKey(Keys.Group))
            {
                PdfDictionary group = new PdfDictionary();
                this.elements["/Group"] = group;
                if (this.document.Options.ColorMode != PdfColorMode.Cmyk)
                    group.Elements.SetName("/CS", "/DeviceRGB");
                else
                    group.Elements.SetName("/CS", "/DeviceCMYK");
                group.Elements.SetName("/S", "/Transparency");
                group.Elements["/I"] = new PdfBoolean(false);
                group.Elements["/K"] = new PdfBoolean(false);
            }
#endif

#if DEBUG_
      PdfItem item = Elements["/MediaBox"];
      if (item != null)
        item.GetType();
#endif
            base.WriteObject(writer);



            //-----------------------//Commented by MaxDna
            //-----------------------//  if (this.orientation == PageOrientation.Landscape)
            //-----------------------//      MediaBox = mediaBox;

        }


Now, with this code, works for some, but not all PDF files that I need to manage.
In my software I need to load existing PDF, add some test annotations in specific positions, ant then save the new PDF.
With these modification, I'm able to Load PDF, Add text annotations in specific places, and save the PDF on:
*) Normal Portrait PDF
*) Normal Landscape PDF (rotation = 90°)

My modification DON'T works well with Landscape PDF with a rotation of 270°, in this case the positioning/rotation of the added TextAnotations is messed up.

I think that PDF rotated by 270° don't works because of the code in the file PdfFormXObject.cs at line 210 and following...

Code:
      // Take /Rotate into account
      PdfRectangle rect = importPage.Elements.GetRectangle(PdfPage.Keys.MediaBox);
      int rotate = importPage.Elements.GetInteger(PdfPage.Keys.Rotate);
      //rotate = 0;
      if (rotate == 0)
      {
        // Set bounding box to media box
        this.Elements["/BBox"] = rect;
      }
      else
      {
        // TODO: Have to adjust bounding box? (I think not, but I'm not sure -> wait for problem)
        this.Elements["/BBox"] = rect;

        // Rotate the image such that it is upright
        XMatrix matrix = new XMatrix();  //XMatrix.Identity;
        double width = rect.Width;
        double height = rect.Height;
        matrix.RotateAtPrepend(-rotate, new XPoint(width / 2, height / 2));

        // Translate the image such that its center lies on the center of the rotated bounding box
        double offset = (height - width) / 2;
        if (height > width)
          matrix.TranslatePrepend(offset, offset);
        else
          matrix.TranslatePrepend(-offset, -offset);

        //string item = "[" + PdfEncoders.ToString(matrix) + "]";
        //Elements[Keys.Matrix] = new PdfLiteral(item);
        Elements.SetMatrix(Keys.Matrix, matrix);
      }


Looking at this code, to me it seem that the possible rotation taken in consideration are "0°" and "not 0°" (90°?)
Probably the "not 0°" should be extended to handle 90°, 180°, 270° rotations separately, but I dont know enough about PDF / PdfSharp internals to try to fix this...


Top
 Profile  
Reply with quote  
PostPosted: Mon Mar 07, 2016 10:19 am 
Offline
PDFsharp Guru
User avatar

Joined: Mon Oct 16, 2006 8:16 am
Posts: 3095
Location: Cologne, Germany
Note to self: also check CropBox when making changes.
See also:
viewtopic.php?p=9799#p9799

_________________
Regards
Thomas Hoevel
PDFsharp Team


Top
 Profile  
Reply with quote  
PostPosted: Mon Jan 09, 2017 8:32 pm 
Offline

Joined: Mon Jan 09, 2017 8:12 pm
Posts: 2
I ran into this issue as well. We are attempting to populate forms from db values rather than having a person type them in. I very quickly was able to open an existing pdf, read the form, and populate fields, then save a new completed form to file. However, one of our forms is part of a larger pdf that sends lots of info, and the info pages are landscape, while the form (the first page) is portrait oriented.

The open/fill/save resulted in a good form, but 1/3 of the landscape data being cut off.

It appears on looking at some outputs that there may be a redundant swapping of height and width values when defining the "MediaBox" object of a "PdfPage" object. I say redundant because you'll see that the orientation is "Landscape" AND the "Rotation" is 90. I have not dived deep into the PdfSharp source code, but hope this will point the way to a quick easy fix for someone that is familiar with the source code.

I have enclosed some example outputs, and a very short "fix" that I implemented in my test to correct the saving of landscaped pages. The red box of the code snippet is the fix, please not that it is AFTER the outputs were generated. The green box in the output is the portrait page that is opened/filled/saved correctly, the red box in the output highlights that the "MediaBox" height and width are actually swapped.

Also note, I tried changing the "Rotation" to 0 and this resulted in the page reading from top to bottom with 1/3 of the info still being cutoff from the top edge. Changing the "Orientation" produced correct results.

Attachment:
File comment: Output Example:
pdfSharpOutput.jpg
pdfSharpOutput.jpg [ 188.65 KiB | Viewed 32192 times ]


Attachment:
File comment: Code Example:
pdfSharpCode.jpg
pdfSharpCode.jpg [ 187.06 KiB | Viewed 32192 times ]


Top
 Profile  
Reply with quote  
PostPosted: Mon Jan 09, 2017 9:29 pm 
Offline
PDFsharp Expert
User avatar

Joined: Sat Mar 14, 2015 10:15 am
Posts: 909
Location: CCAA
kevin.gregg wrote:
It appears on looking at some outputs that there may be a redundant swapping of height and width values when defining the "MediaBox" object of a "PdfPage" object.
Please try the change proposed here:
viewtopic.php?p=9591#p9591

_________________
Best regards
Thomas
(Freelance Software Developer with several years of MigraDoc/PDFsharp experience)


Top
 Profile  
Reply with quote  
PostPosted: Thu Apr 05, 2018 8:09 pm 
Offline
PDFsharp Expert
User avatar

Joined: Sat Mar 14, 2015 10:15 am
Posts: 909
Location: CCAA
Hi!
TH-Soft wrote:
I made an experimental change in class PdfPage.cs
I undid the change from 2015 and tried something new.

The new code works for the situation described in this thread and also for the issue reported yesterday.
Other issue here:
viewtopic.php?p=11542#p11542

_________________
Best regards
Thomas
(Freelance Software Developer with several years of MigraDoc/PDFsharp experience)


Top
 Profile  
Reply with quote  
PostPosted: Sun Apr 08, 2018 4:48 pm 
Offline
PDFsharp Expert
User avatar

Joined: Sat Mar 14, 2015 10:15 am
Posts: 909
Location: CCAA
With PDFsharp 1.50 RC2 situation is not yet perfect.

When opening files for modification I have to set
Code:
page.Orientation = PageOrientation.Portrait;

This has no effect if rotation is 0 or 180, but it is needed to get correct results when rotation is 90 or 270.

This hack is not needed when rotated PDF pages are used with XPdfForm and drawn on other PDF pages.

_________________
Best regards
Thomas
(Freelance Software Developer with several years of MigraDoc/PDFsharp experience)


Top
 Profile  
Reply with quote  
PostPosted: Tue Jun 25, 2019 2:54 am 
Offline

Joined: Wed Sep 28, 2016 10:44 pm
Posts: 6
Location: Kona, Hawaii
I'm having issues with this as well (using 1.5 beta 3) when importing PDF pages that are rotated (270 deg). Probably the getting latest code will address the immediate issue, but I'm afraid of inadvertently introducing other bugs.

The PDF spec doesn't really have the concept of "Orientation", does it? I don't think orientation (portrait/landscape) should be confused with actual rotation. There should be a clear distinction between rotating content or merely changing the dimensions (MediaBox) of the page.


Top
 Profile  
Reply with quote  
PostPosted: Tue Jun 25, 2019 5:38 am 
Offline
PDFsharp Expert
User avatar

Joined: Sat Mar 14, 2015 10:15 am
Posts: 909
Location: CCAA
bradleypeet wrote:
I'm having issues with this as well (using 1.5 beta 3)
Improvements that were made for RC2 are not part of beta 3, so what do you expect?
Jump into the water and try 1.50 stable.

_________________
Best regards
Thomas
(Freelance Software Developer with several years of MigraDoc/PDFsharp experience)


Top
 Profile  
Reply with quote  
PostPosted: Tue Jun 25, 2019 11:27 pm 
Offline

Joined: Wed Sep 28, 2016 10:44 pm
Posts: 6
Location: Kona, Hawaii
TH-Soft wrote:
Improvements that were made for RC2 are not part of beta 3, so what do you expect?
Jump into the water and try 1.50 stable.


Sorry I wasn't clear. Looking at the latest PdfPage.cs code on Github I still see "HACK" and "TODO" and mention of a yet-to-be-implemented "cleaner approach" in the comments for those changes made over a year ago. The question I should have asked is this: might there be a proper fix available in the near future or is RC2 as good as it gets?


Top
 Profile  
Reply with quote  
PostPosted: Wed Jun 26, 2019 7:52 am 
Offline
PDFsharp Guru
User avatar

Joined: Mon Oct 16, 2006 8:16 am
Posts: 3095
Location: Cologne, Germany
bradleypeet wrote:
The question I should have asked is this: might there be a proper fix available in the near future or is RC2 as good as it gets?
The answer is: definitely maybe.
The changes made for RC2 allowed all my testcases to give correct results; the only drawback is that some testcases require code on the client side that should not be there.
So there is potential for a still better solution, but I don't know when/if it will come. At the moment I have more attractive spare-time activities...

_________________
Regards
Thomas Hoevel
PDFsharp Team


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 13 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 50 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Privacy Policy, Data Protection Declaration, Impressum
Powered by phpBB® Forum Software © phpBB Group