Hello
after much testing, I've come up with different code to try to fix this bug:
Modification 1Code:
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...