Convert PDF to XPS

None
8/25/2015

In this sample you can see how you convert your PDF document to an XPS format (which is Microsoft Windows' version of PDF). At this time TallComponents only offer conversion of PDF to XPS but not the other way around. As stated in the sample, the XPS document generated by the standard XPS namespace is not very efficient: images are stored uncompressed at full resolution. In the download folder of PDF Rasterizer we also provide a large code sample of how to circumvent the XPS' storage function and how you can efficiently convert your PDF to XPS.

using System;
using System.IO;
using System.Windows.Documents;
using System.Windows.Documents.Serialization;
using System.Windows.Xps;
using System.Windows.Xps.Packaging;

using TallComponents.PDF.Rasterizer;
using TallComponents.PDF.Rasterizer.Fonts;
using TallComponents.PDF.Rasterizer.Configuration;
using TallComponents.PDF.Rasterizer.Diagnostics;

namespace ConvertToXPSDocument
{
    class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            Document d;
            using (FileStream fs = new FileStream(@"..\..\input.pdf", FileMode.Open, FileAccess.Read))
            {
                d = new Document(fs);
            }
            XpsDocument xpsd = new XpsDocument(@"..\..\output.xps", FileAccess.Write);
            XpsDocumentWriter writer = XpsDocument.CreateXpsDocumentWriter(xpsd);

            SerializerWriterCollator collator = writer.CreateVisualsCollator();
            collator.BeginBatchWrite();

            RenderSettings renderSettings = new RenderSettings();
            renderSettings.TextSettings.ResolveFont += new ResolveFontEventHandler(TextSettings_ResolveFont);

            ConvertToWpfOptions convertOptions = new ConvertToWpfOptions();
            Summary summary = new Summary();

            int count = d.Pages.Count;

            foreach(Page p in d.Pages)
            {
                FixedPage fixedPage = p.ConvertToWpf(renderSettings, convertOptions, summary);

                // The ticket below determines the size of the page. so we must pass one if we
                // want the XPS page to assume the size of the pdf page.
                System.Printing.PrintTicket ticket = new System.Printing.PrintTicket();
                ticket.PageMediaSize = new System.Printing.PageMediaSize(fixedPage.Width, fixedPage.Height);

                // We return pages with a single canvas as their child. WPF does not allow us
                // to pass a FixedPage to the collator, but we can pass the canvas. Alternatively,
                // it appears to be possible to turn a fixed page into a "visual" that can be
                // used, but that is a bit 'irky'.
                collator.Write(fixedPage.Children[0], ticket);

                // Note: XPS can become big if images are involved, as they appear to be put in the
                // file at full resolution, no matter what the output resolution is. Also: they
                // are all converted to PNGs, so JPEG compression gets lost.
            }
            collator.EndBatchWrite();
            xpsd.Close();
        }

        static void TextSettings_ResolveFont(TextRenderSettings sender, ResolveFontEventArgs args)
        {
            System.Diagnostics.Trace.WriteLine(String.Format("font ({0}, {1}, {2})", args.PdfFontName, args.SystemFontName, args.FontPath));

            if (args.FontLocation != FontLocation.System)
            {
                switch (args.PdfFontName)
                {
                    case "Times-Roman":
                        args.SystemFontName = "Times New Roman";
                        break;
                    case "Times-Bold":
                        args.SystemFontName = "Times New Roman";
                        args.Bold = true;
                        break;
                    case "Times-Italic":
                        args.SystemFontName = "Times New Roman";
                        args.Italic = true;
                        break;
                    case "Helvetica":
                        args.SystemFontName = "Arial Unicode MS";
                        break;
                    case "Helvetica-Bold":
                        args.SystemFontName = "Arial Unicode MS";
                        args.Bold = true;
                        break;
                    case "Helvetica-Italic":
                        args.SystemFontName = "Arial Unicode MS";
                        args.Italic = true;
                        break;
                }
            }
        }
    }
}