// =========================================================================== //  ©2013-2026 WebSupergoo. All rights reserved. // //  This source code is for use exclusively with the ABCpdf product with //  which it is distributed, under the terms of the license for that //  product. Details can be found at // //    http://www.websupergoo.com/ // //  This copyright notice must not be deleted and must be reproduced alongside //  any sections of code extracted from this module. // =========================================================================== using System; using System.Collections.Generic; using System.Text; using System.IO; using WebSupergoo.FontUnembedment; using WebSupergoo.ABCpdf14; namespace FontUnembedment {   class Program {     static void Main(string[] args) {       //Always manually check the output for problems.       string inputFile = MapPath("input.pdf");       string outputFile = MapPath("output.pdf");       FontUnembedder unembedder = new FontUnembedder();       // The regular Times is called Times Roman, not Times,       // so the fonts for different styles are added separately.       unembedder.AddFont("Times Roman", LanguageType.Latin);       unembedder.AddFont("Times Bold", LanguageType.Latin);       unembedder.AddFont("Times Italic", LanguageType.Latin);       unembedder.AddFont("Times Bold Italic", LanguageType.Latin);       unembedder.AddFont("Helvetica", LanguageType.Latin);       unembedder.AddFont("Courier", LanguageType.Latin);       unembedder.AddFont("Symbol", LanguageType.Latin);       unembedder.AddFont("Times New Roman", LanguageType.Latin);       unembedder.AddFont("Arial", LanguageType.Latin);       unembedder.AddFont("Courier New", LanguageType.Latin);       unembedder.AddFont("Wingdings", LanguageType.Latin);       unembedder.AddFont("Verdana", LanguageType.Latin);       unembedder.AddFont("MingLiU", LanguageType.ChineseT);       unembedder.AddFont("PMingLiU", LanguageType.ChineseT);       // Some software changes the names of MingLiU and PMingLiU       // on Traditional Chinese Windows to "___" and "____" because       // the font names are 3 or 4 Chinese characters.       // You'll need to change "___" and "____" depending on       // the font names in the PDF files.       //unembedder.AddFont("___", "MingLiU", LanguageType.ChineseT);       //unembedder.AddFont("____", "PMingLiU", LanguageType.ChineseT);       using(Doc doc = new Doc()) {         doc.Read(inputFile);         SortedDictionary<int, bool> fonts = new SortedDictionary<int, bool>();         for(int i = 1, count = doc.ObjectSoup.Count; i<count; ++i) {           if(doc.GetInfo(i, "Type")=="font") {             if(!fonts.ContainsKey(i))               fonts.Add(i, false);             int descendant = doc.GetInfoInt(i, "/DescendantFonts*[0]:Ref");             if(descendant!=0)               fonts[descendant] = true;           }         }         List<FontUnembedder.ProcessingInfo> infos = new List<FontUnembedder.ProcessingInfo>();         unembedder.Process(doc, infos);         for(int i = 0; i<infos.Count; ++i) {           FontUnembedder.ProcessingInfo info = infos[i];           Console.WriteLine("{0} {1} (ID:{2}, Language:{3}) {4} characters:",             i+1, Quote(doc.GetInfo(info.FontId, "/BaseFont*:Name")),             info.FontId, info.Language, info.CharacterCount);           List<FontUnembedder.FontObjectInfo> list = info.SourceFonts;           for(int j = 0; j<list.Count; ++j) {             FontUnembedder.FontObjectInfo sourceFont = list[j];             Console.WriteLine(sourceFont.Id==0?             "    {0} {2}": "    {0} (ID:{1}) {2}",               Quote(sourceFont.Name), sourceFont.Id,               sourceFont.EncodingIsIdentical? "identical encoding":               string.Format("{0} characters", sourceFont.CharacterCount));             if(sourceFont.Id!=0)               fonts.Remove(sourceFont.Id);           }         }         int k = 0;         foreach(KeyValuePair<int, bool> pair in fonts) {           if(!pair.Value) {             if(k<=0)               Console.WriteLine();             Console.WriteLine("{0} {1} (ID:{2}) not processed.",               k+1, Quote(doc.GetInfo(pair.Key, "/BaseFont*:Name")), pair.Key);             ++k;           }         }         doc.Save(outputFile);       }     }     private static string Quote(string s) {       char[] whiteSpaces = {         '\0', ' ', '\t', '\n', '\r', '\v', '\f', '\x85', '\u00a0', '\u1680',         '\u2000', '\u2001', '\u2002', '\u2003', '\u2004', '\u2005',         '\u2006', '\u2007', '\u2008', '\u2009', '\u200a', '\u200b',         '\u2028', '\u2029', '\u3000', '\ufeff'       };       return s.IndexOfAny(whiteSpaces)<0? s: '"'+s+'"';     }     private static string MapPath(string fileName) {       string basePath = Directory.GetCurrentDirectory();       return Path.Combine(Directory.GetParent(basePath).Parent.FullName, fileName);     }   } }