Link to home
Start Free TrialLog in
Avatar of Scott Fell
Scott FellFlag for United States of America

asked on

PDF Sharp: Rotate One Line Of Text

Starting with some example code found at pdfsharp, I modified it to crate a bates stamp to an existing pdf. In this case it is just looking in a folder and combining any pdf's in the specified folder to make a new pdf, then adding a numbering system at the very bottom.

using System.Diagnostics;
using System.Collections;
using System.Globalization;
using System.IO;
using PdfSharp.Pdf;
using PdfSharp.Pdf.IO;
using PdfSharp.Drawing;

namespace ConcatenateDocuments
{
    /// <summary>
    /// This sample shows how to concatenate the pages of several PDF documents to
    /// one single file.
    /// </summary>
    class Program
    {
        static void Main()
        {

            Variant3();

        }

        /// <summary>
        /// Put your own code here to get the files to be concatenated.
        /// </summary>
        static string[] GetFiles()
        {
            var dirInfo = new DirectoryInfo("./results");
            var fileInfos = dirInfo.GetFiles("*.pdf");
            var list = new ArrayList();
            

            foreach (var info in fileInfos)
            {
                // HACK: Just skip the protected samples file...
                if (info.Name.IndexOf("protected", System.StringComparison.Ordinal) == -1)
                    list.Add(info.FullName);
            }
            return (string[])list.ToArray(typeof(string));
        }

        /// <summary>
        /// Imports all pages from a list of documents.
        /// </summary>


        /// <summary>
        /// This sample adds a consecutive number in the middle of each page.
        /// It shows how you can add graphics to an imported page.
        /// </summary>
        static void Variant3()
        {
            // Get some file names.
            var files = GetFiles();

            // Open the output document.
            var outputDocument = new PdfDocument();

            // Note that the output document may be significantly larger than in Variant1.
            // This is because adding graphics to an imported page causes the 
            // decompression of its content if it was compressed in the external document.
            // To compare file sizes you should either run the sample as Release build
            // or uncomment the following line.
            outputDocument.Options.CompressContentStreams = true;

            var font = new XFont("Verdana", 10, XFontStyle.Regular);
            var number = 0;

            var orientation = 0;

            // Iterate the files.
            foreach (var file in files)
            {
                // Open the document to import pages from it.
                var inputDocument = PdfReader.Open(file, PdfDocumentOpenMode.Import);

                // Iterate the pages.
                var count = inputDocument.PageCount;
                for (var idx = 0; idx < count; idx++)
                {
                    // Get the page from the external document...
                    var page = inputDocument.Pages[idx];
                    // ...and add it to the output document.
                    // Note that the PdfPage instance returned by AddPage is a
                    // different object.

                    page = outputDocument.AddPage(page);

                    orientation = page.Rotate;


                    XGraphics gfx = XGraphics.FromPdfPage(page);
                    XRect rect = new XRect(new XPoint(), gfx.PageSize);
                    //rect.Inflate(-15, -20);
                    rect.Inflate(0, 0);

                    XStringFormat format = new XStringFormat
                    {
                        Alignment = XStringAlignment.Near,
                        LineAlignment = XLineAlignment.Far

                    };

                    //gfx.RotateTransform(-90);  <<---- NOT WORKING

                    gfx.DrawString($"BATES_200{++number} height: {page.Height} width: {page.Width} O: {orientation}", font, XBrushes.Black, rect, format);


                }
            }

            // Save the document...
            const string filename = "testpdf.pdf";
            outputDocument.Save(filename);
            // ...and start a viewer.
            Process.Start(filename);
        }

        
    }    
}

Open in new window


The code works as expected only if the pdf is created normally such as being printed or scanned fed landscape.  The problem I am having is when a multi function device is used and documents are scanned in portrait, the scanner rotates the page 270.  When this happens, the 'footer' I am adding ends up what appears vertically along the right side.  What I need to do is have this text rotated -90.

On line 90 above, I have commented out
      //gfx.RotateTransform(-90);  <<---- NOT WORKING

Open in new window

When I comment that code, the content created by gfx.DrawString( does not get put on the page.

I am just looking to get this part working.  Once done,I will add the test to see if the page is rotated 270 and only then add this line.
portrait.pdf
landscape.pdf
Avatar of J0rtIT
J0rtIT
Flag of Venezuela, Bolivarian Republic of image

probably it doesn't accept negative values. try rotating with positive value which is equal to 270.
line is not 90 is 105
Avatar of Scott Fell

ASKER

Jose, I tried positive numbers too. There must be an error because when I uncomment line 105 (thanks for the catch), the code that generates the ext on line 107 does not print.
Scott could you try to put your code into a GitHub private or public to check it out together?
I created a command line project. My code is in the question. I just added pdfsharp from nuget.

Is that enough to get you going?  Otherwise, I will zip it up.  I will also upload some example pdf files to illustrate the difference between being scanned in portrait or landscape.
I have added two PDF files. One is scanned in as landscape and the other is portrait. When you view either in adobe reader or acrobat, you will see they are both 8.5 X 11 landscape. However, on line 88-90 you will see I have
page = outputDocument.AddPage(page);

orientation = page.Rotate;

Open in new window

and the orientation is reported as 0 for the page scanned as landscape and 270 when scanned portrait.  So visually they are the same, but the underlying originals are not.  When this code is run, the landscape scanned document will produce the added bates footer at the bottom and for the portrait scanned doc the line is vertically aligned with the right edge.

All I need to know is what to do to rotate the line. I can take care of the logic for when it should be rotated.
Ok will do the testing
Hi Scott,

I am sorry, but you are drawing strings directly on the PDF pages. Any specific reason, in not using Annotations?
http://www.pdfsharp.net/wiki/Annotations-sample.ashx?AspxAutoDetectCookieSupport=1

Regards,
Chinmay.
Let me give it a try!
Wait, an annotation is the wrong thing. An annotation creates a little icon to hover and reveal some content. I am simply looking to apply some text to the bottom of every page. What I have works if the orientation is not set to 270 (scanned portrait)
If I run any of the sample code, the same thing happens.

It has something to do with rotating the rectangle
ASKER CERTIFIED SOLUTION
Avatar of Scott Fell
Scott Fell
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I am still monitoring this, if anybody has found a work around, I would be happy to hear about it.

Thank you.
I have an update on this.

"Not working" is ambiguous. As it turned out, the text was was being rotated, just going off the page.

Instead of      
gfx.RotateTransform(some_point) 

Open in new window

           
I used RotateAtTRansform to set where the object should rotate at.  Took some trial and error for the exact points, but now works as expected.
gfx.RotateAtTransform(angle, new XPoint(point_x, point_y));

Open in new window