/// <summary> /// Given a book, typically one in a temporary folder made just for exporting (or testing), /// and given the set of fonts found while creating that book and removing hidden elements, /// find the files needed for those fonts. /// 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="fontFileFinder">use new FontFinder() for real, or a stub in testing</param> public static void EmbedFonts(Book.Book book, IWebSocketProgress progress, HashSet <string> fontsWanted, IFontFinder fontFileFinder) { const string defaultFont = "Andika New Basic"; // already in BR, don't need to embed or make rule. fontsWanted.Remove(defaultFont); PublishHelper.CheckFontsForEmbedding(progress, fontsWanted, fontFileFinder, out List <string> filesToEmbed, out HashSet <string> badFonts); 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) { if (badFonts.Contains(font)) { continue; } 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"); // Repair defaultLangStyles.css and other places in the output book if needed. if (badFonts.Any()) { PublishHelper.FixCssReferencesForBadFonts(book.FolderPath, defaultFont, badFonts); PublishHelper.FixXmlDomReferencesForBadFonts(book.OurHtmlDom.RawDom, defaultFont, badFonts); } }