Exemple #1
0
        public static int Handle(GetUsedFontsParameters options)
        {
            if (!Directory.Exists(options.BookPath))
            {
                if (options.BookPath.Contains(".htm"))
                {
                    Debug.WriteLine("Supply only the directory, not the path to the file.");
                    Console.Error.WriteLine("Supply only the directory, not the path to the file.");
                }
                else
                {
                    Debug.WriteLine("Could not find " + options.BookPath);
                    Console.Error.WriteLine("Could not find " + options.BookPath);
                }
                return(1);
            }
            Console.WriteLine("Gathering font data.");

            // Some of this might be useful if we end up needing to instantiate the book to figure out what
            // is REALLY needed (as opposed to just mentioned in a style sheet).
            //var collectionFolder = Path.GetDirectoryName(options.BookPath);
            //var projectSettingsPath = Directory.GetFiles(collectionFolder, "*.bloomCollection").FirstOrDefault();
            //var collectionSettings = new CollectionSettings(projectSettingsPath);

            //XMatterPackFinder xmatterFinder = new XMatterPackFinder(new[] {BloomFileLocator.GetInstalledXMatterDirectory()});
            //var locator = new BloomFileLocator(collectionSettings, xmatterFinder, ProjectContext.GetFactoryFileLocations(),
            //	ProjectContext.GetFoundFileLocations(), ProjectContext.GetAfterXMatterFileLocations());

            //var bookInfo = new BookInfo(options.BookPath, true);
            //var book = new Book.Book(bookInfo, new BookStorage(options.BookPath, locator, new BookRenamedEvent(), collectionSettings),
            //	null, collectionSettings, null, null, new BookRefreshEvent());

            //book.BringBookUpToDate(new NullProgress());

            var fonts = EpubMaker.GetFontsUsed(options.BookPath, false).ToList();

            fonts.Sort();

            Directory.CreateDirectory(Path.GetDirectoryName(options.ReportPath));

            using (var report = new StreamWriter(options.ReportPath))
            {
                foreach (var font in fonts)
                {
                    report.WriteLine(font);
                }
            }
            Console.WriteLine("Finished gathering font data.");
            Debug.WriteLine("Finished gathering font data.");
            return(0);
        }
Exemple #2
0
        /// <summary>
        /// Given a book, typically one in a temporary folder made just for exporting (or testing),
        /// examine the CSS files and determine what fonts should be necessary. (Enhance: we could actually
        /// load the book into a DOM and find out what font IS used for each block.)
        /// Copy the font file for the normal style of that font family from the system font folder,
        /// if permitted; or post a warning in progress if we can't embed it.
        /// Create an extra css file (fonts.css) which tells the book to find the font files for those font families
        /// in the local folder, and insert a link to it into the book.
        /// </summary>
        /// <param name="book"></param>
        /// <param name="progress"></param>
        /// <param name="fontFileFinder">use new FontFinder() for real, or a stub in testing</param>
        public static void EmbedFonts(Book book, IWebSocketProgress progress, IFontFinder fontFileFinder)
        {
            const string defaultFont = "Andika New Basic";             // already in BR, don't need to embed or make rule.
            // The 'false' here says to ignore all but the first font face in CSS's ordered lists of desired font faces.
            // If someone is publishing an Epub, they should have that font showing. For one thing, this makes it easier
            // for us to not embed fonts we don't want/ need.For another, it makes it less likely that an epub will look
            // different or have glyph errors when shown on a machine that does have that primary font.
            var fontsWanted = EpubMaker.GetFontsUsed(book.FolderPath, false).ToList();

            fontsWanted.Remove(defaultFont);
            fontFileFinder.NoteFontsWeCantInstall = true;
            var filesToEmbed = new List <string>();

            foreach (var font in fontsWanted)
            {
                var fontFiles = fontFileFinder.GetFilesForFont(font);
                if (fontFiles.Count() > 0)
                {
                    filesToEmbed.AddRange(fontFiles);
                    progress.MessageWithParams("CheckFontOK", "{0} is a font name", "Checking {0} font: License OK for embedding.", font);
                    // Assumes only one font file per font; if we embed multiple ones will need to enhance this.
                    var size         = new FileInfo(fontFiles.First()).Length;
                    var sizeToReport = (size / 1000000.0).ToString("F1");                     // purposely locale-specific; might be e.g. 1,2
                    progress.MessageWithColorAndParams("Embedding",
                                                       "{1} is a number with one decimal place, the number of megabytes the font file takes up",
                                                       "blue",
                                                       "Embedding font {0} at a cost of {1} megs",
                                                       font, sizeToReport);
                    continue;
                }
                if (fontFileFinder.FontsWeCantInstall.Contains(font))
                {
                    progress.ErrorWithParams("LicenseForbids", "{0} is a font name", "Checking {0} font: License does not permit embedding.", font);
                }
                else
                {
                    progress.ErrorWithParams("NoFontFound", "{0} is a font name", "Checking {0} font: No font found to embed.", font);
                }
                progress.ErrorWithParams("SubstitutingAndika", "{0} and {1} are font names", "Substituting \"{0}\" for \"{1}\"", defaultFont, font);
            }
            foreach (var file in filesToEmbed)
            {
                // Enhance: do we need to worry about problem characters in font file names?
                var dest = Path.Combine(book.FolderPath, Path.GetFileName(file));
                RobustFile.Copy(file, dest);
            }
            // Create the fonts.css file, which tells the browser where to find the fonts for those families.
            var sb = new StringBuilder();

            foreach (var font in fontsWanted)
            {
                var group = fontFileFinder.GetGroupForFont(font);
                if (group != null)
                {
                    EpubMaker.AddFontFace(sb, font, "normal", "normal", group.Normal);
                }
                // We don't need (or want) a rule to use Andika instead.
                // The reader typically WILL use Andika, because we have a rule making it the default font
                // for the whole body of the document, and BloomReader always has it available.
                // However, it's possible that although we aren't allowed to embed the desired font,
                // the device actually has it installed. In that case, we want to use it.
            }
            RobustFile.WriteAllText(Path.Combine(book.FolderPath, "fonts.css"), sb.ToString());
            // Tell the document to use the new stylesheet.
            book.OurHtmlDom.AddStyleSheet("fonts.css");
        }