1cb93a386Sopenharmony_ci/*
2cb93a386Sopenharmony_ci * Copyright 2016 Google Inc.
3cb93a386Sopenharmony_ci *
4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be
5cb93a386Sopenharmony_ci * found in the LICENSE file.
6cb93a386Sopenharmony_ci */
7cb93a386Sopenharmony_ci
8cb93a386Sopenharmony_ci/*
9cb93a386Sopenharmony_ciCompile with:
10cb93a386Sopenharmony_ci
11cb93a386Sopenharmony_ci    "...../csc" \
12cb93a386Sopenharmony_ci        /lib:"....." \
13cb93a386Sopenharmony_ci        /reference:"ReachFramework.dll" \
14cb93a386Sopenharmony_ci        /reference:"WindowsBase.dll" \
15cb93a386Sopenharmony_ci        /reference:"PresentationCore.dll" \
16cb93a386Sopenharmony_ci        /reference:"PresentationFramework.dll" \
17cb93a386Sopenharmony_ci        xps_to_png.cs
18cb93a386Sopenharmony_ci
19cb93a386Sopenharmony_ci*/
20cb93a386Sopenharmony_ci// logic inspired by this example: https://goo.gl/nCxrjQ
21cb93a386Sopenharmony_ciclass Program {
22cb93a386Sopenharmony_ci    static int ceil(double x) { return (int)System.Math.Ceiling(x); }
23cb93a386Sopenharmony_ci    static void convert(double dpi, string path, string out_path) {
24cb93a386Sopenharmony_ci        double scale = dpi / 96.0;
25cb93a386Sopenharmony_ci        System.Windows.Xps.Packaging.XpsDocument xpsDoc =
26cb93a386Sopenharmony_ci                new System.Windows.Xps.Packaging.XpsDocument(
27cb93a386Sopenharmony_ci                        path, System.IO.FileAccess.Read);
28cb93a386Sopenharmony_ci        if (xpsDoc == null) {
29cb93a386Sopenharmony_ci            throw new System.Exception("XpsDocumentfailed");
30cb93a386Sopenharmony_ci        }
31cb93a386Sopenharmony_ci        System.Windows.Documents.FixedDocumentSequence docSeq =
32cb93a386Sopenharmony_ci                xpsDoc.GetFixedDocumentSequence();
33cb93a386Sopenharmony_ci        if (docSeq == null) {
34cb93a386Sopenharmony_ci            throw new System.Exception("GetFixedDocumentSequence failed");
35cb93a386Sopenharmony_ci        }
36cb93a386Sopenharmony_ci        System.Windows.Documents.DocumentReferenceCollection drc = docSeq.References;
37cb93a386Sopenharmony_ci        int index = 0;
38cb93a386Sopenharmony_ci        foreach (System.Windows.Documents.DocumentReference dr in drc) {
39cb93a386Sopenharmony_ci            System.Windows.Documents.FixedDocument dp = dr.GetDocument(false);
40cb93a386Sopenharmony_ci            foreach (System.Windows.Documents.PageContent pc in dp.Pages) {
41cb93a386Sopenharmony_ci                System.Windows.Documents.FixedPage fixedPage = pc.GetPageRoot(false);
42cb93a386Sopenharmony_ci                double width = fixedPage.Width;
43cb93a386Sopenharmony_ci                double height = fixedPage.Height;
44cb93a386Sopenharmony_ci                System.Windows.Size sz = new System.Windows.Size(width, height);
45cb93a386Sopenharmony_ci                fixedPage.Measure(sz);
46cb93a386Sopenharmony_ci                fixedPage.Arrange(
47cb93a386Sopenharmony_ci                        new System.Windows.Rect(new System.Windows.Point(), sz));
48cb93a386Sopenharmony_ci                fixedPage.UpdateLayout();
49cb93a386Sopenharmony_ci                System.Windows.Media.Imaging.BitmapImage bitmap =
50cb93a386Sopenharmony_ci                        new System.Windows.Media.Imaging.BitmapImage();
51cb93a386Sopenharmony_ci                System.Windows.Media.Imaging.RenderTargetBitmap renderTarget =
52cb93a386Sopenharmony_ci                        new System.Windows.Media.Imaging.RenderTargetBitmap(
53cb93a386Sopenharmony_ci                            ceil(scale * width), ceil(scale * height), dpi, dpi,
54cb93a386Sopenharmony_ci                            System.Windows.Media.PixelFormats.Default);
55cb93a386Sopenharmony_ci                renderTarget.Render(fixedPage);
56cb93a386Sopenharmony_ci                System.Windows.Media.Imaging.BitmapEncoder encoder =
57cb93a386Sopenharmony_ci                    new System.Windows.Media.Imaging.PngBitmapEncoder();
58cb93a386Sopenharmony_ci                encoder.Frames.Add(
59cb93a386Sopenharmony_ci                        System.Windows.Media.Imaging.BitmapFrame.Create(renderTarget));
60cb93a386Sopenharmony_ci                string filename = string.Format("{0}_{1}.png", out_path, index);
61cb93a386Sopenharmony_ci                System.IO.FileStream pageOutStream = new System.IO.FileStream(
62cb93a386Sopenharmony_ci                    filename, System.IO.FileMode.Create, System.IO.FileAccess.Write);
63cb93a386Sopenharmony_ci                encoder.Save(pageOutStream);
64cb93a386Sopenharmony_ci                pageOutStream.Close();
65cb93a386Sopenharmony_ci                System.Console.WriteLine(filename);
66cb93a386Sopenharmony_ci                ++index;
67cb93a386Sopenharmony_ci            }
68cb93a386Sopenharmony_ci        }
69cb93a386Sopenharmony_ci    }
70cb93a386Sopenharmony_ci    // Executes convert, catching thrown exceptions, and printing them
71cb93a386Sopenharmony_ci    // to stdout, and exiting immediately.
72cb93a386Sopenharmony_ci    static void try_convert(double dpi, string path, string out_path) {
73cb93a386Sopenharmony_ci        try {
74cb93a386Sopenharmony_ci            convert(dpi, path, out_path);
75cb93a386Sopenharmony_ci        } catch (System.Exception e) {
76cb93a386Sopenharmony_ci            System.Console.WriteLine(e);
77cb93a386Sopenharmony_ci            System.Environment.Exit(1);
78cb93a386Sopenharmony_ci        }
79cb93a386Sopenharmony_ci    }
80cb93a386Sopenharmony_ci    // For each command line argument, convert xps to sequence of pngs.
81cb93a386Sopenharmony_ci    static void Main(string[] args) {
82cb93a386Sopenharmony_ci        double dpi = 72.0;
83cb93a386Sopenharmony_ci        if (args.Length == 0) {
84cb93a386Sopenharmony_ci            System.Console.WriteLine("usage:\n\txps_to_png [-dDPI] [XPS_FILES]\n\n");
85cb93a386Sopenharmony_ci            System.Environment.Exit(1);
86cb93a386Sopenharmony_ci        }
87cb93a386Sopenharmony_ci        System.Collections.Generic.List<string> xpsFiles =
88cb93a386Sopenharmony_ci                new System.Collections.Generic.List<string>();
89cb93a386Sopenharmony_ci        foreach (string arg in args) {
90cb93a386Sopenharmony_ci            string flag = "-d";
91cb93a386Sopenharmony_ci            if (arg.StartsWith(flag)) {
92cb93a386Sopenharmony_ci                dpi = System.Convert.ToDouble(arg.Remove(0, flag.Length));
93cb93a386Sopenharmony_ci            } else if (System.IO.File.Exists(arg)) {
94cb93a386Sopenharmony_ci                xpsFiles.Add(arg);
95cb93a386Sopenharmony_ci            } else {
96cb93a386Sopenharmony_ci                System.Console.WriteLine("file missing: '" + arg + "'\n\n");
97cb93a386Sopenharmony_ci                System.Environment.Exit(1);
98cb93a386Sopenharmony_ci            }
99cb93a386Sopenharmony_ci        }
100cb93a386Sopenharmony_ci        foreach (string file in xpsFiles) {
101cb93a386Sopenharmony_ci            System.Threading.Thread t = new System.Threading.Thread(
102cb93a386Sopenharmony_ci                    () => try_convert(dpi, file, file));
103cb93a386Sopenharmony_ci            t.SetApartmentState(System.Threading.ApartmentState.STA);
104cb93a386Sopenharmony_ci            t.Start();
105cb93a386Sopenharmony_ci        }
106cb93a386Sopenharmony_ci    }
107cb93a386Sopenharmony_ci}
108