/** Autodetect fonts available on the system. */ public static final void discoverPhysicalFonts() throws Exception { // Currently we use FOP - inspired by org.apache.fop.render.PrintRendererConfigurator // iText also has a font discoverer (which we could use // instead, but don't, since in docx4j we're settled on // PDF output via XSL FO) FontFileFinder fontFileFinder = new FontFileFinder(); // Automagically finds a list of font files on local system // based on os.name List fontFileList = fontFileFinder.find(); if (regex == null) { for (Iterator iter = fontFileList.iterator(); iter.hasNext(); ) { URL fontUrl = getURL(iter.next()); // parse font to ascertain font info addPhysicalFont(fontUrl); } } else { Pattern pattern = Pattern.compile(regex); for (Iterator iter = fontFileList.iterator(); iter.hasNext(); ) { URL fontUrl = getURL(iter.next()); // parse font to ascertain font info if (pattern.matcher(fontUrl.toString()).matches()) { addPhysicalFont(fontUrl); } else { // log.debug("Ignoring " + fontUrl.toString() ); } } } // Add fonts from our Temporary Embedded Fonts dir fontFileList = fontFileFinder.find(ObfuscatedFontPart.getTemporaryEmbeddedFontsDir()); for (Iterator iter = fontFileList.iterator(); iter.hasNext(); ) { URL fontUrl = getURL(iter.next()); addPhysicalFont(fontUrl); } fontCache.save(); }
/** * Add a physical font's EmbedFontInfo object. * * @param fontUrl eg new java.net.URL("file:" + path) */ public static void addPhysicalFont(URL fontUrl) { addPhysicalFont(null, fontUrl); }
/** * deObfuscate this font, and save it using fontName * * @param fontName - the name to save the font as. We could read the font name from the * deObfuscated data, but FontLoader can't readily load from a byte array. * @param fontKey */ public void deObfuscate(String fontName, String fontKey) { byte[] fontData = null; bb.clear(); fontData = new byte[bb.capacity()]; bb.get(fontData, 0, fontData.length); log.debug("bytes: " + fontData.length); log.info("deObfuscating with fontkey: " + fontKey); // INPUT: {1DF903E3-2F14-4575-8028-881FEBABF2AB} // See http://openiso.org/Ecma/376/Part4/2.8.1 // for how to do this. // First, strip {,} String tmpString = fontKey.substring(1, fontKey.length() - 1); log.debug(tmpString); // Now strip - String guidString = tmpString.replace(target, replacement); log.debug(guidString); // Make the font key into a byte array byte[] guidByteArray = new byte[16]; for (int i = 0; i < guidByteArray.length; i++) { guidByteArray[i] = fromHexString(guidString.substring(i * 2, (i * 2) + 2)); } // XOR the reverse of the guidByteArray with // the first and second 16 bytes for (int j = 0; j < 2; j++) { for (int i = 0; i < 16; i++) { fontData[(j * 16) + i] ^= guidByteArray[15 - i]; // Reverse happens here } } // Save the result java.io.File f = new File(tmpFontDir, fontName + ".ttf"); String path = null; java.io.FileOutputStream fos = null; try { path = f.getCanonicalPath(); fos = new java.io.FileOutputStream(f); fos.write(fontData); log.debug("wrote: " + fontData.length); fos.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } log.info("Done!"); // Save to "Temporary Font Files" directory. FontResolver fontResolver = FontSetup.createMinimalFontResolver(); if (log.isDebugEnabled()) { CustomFont customFont = null; try { log.debug("Loading from: " + path); String subFontName = null; // TODO set this if its a TTC boolean embedded = true; boolean useKerning = true; customFont = FontLoader.loadFont( "file:" + path, subFontName, embedded, EncodingMode.AUTO, useKerning, fontResolver); } catch (Exception e) { e.printStackTrace(); } if (customFont != null) { log.info("Successfully reloaded " + customFont.getFontName()); if (customFont.isEmbeddable()) { log.debug("confirmed embeddable"); } else { // Sanity check log.error("this embedded font claims it is not embeddable!"); } } } // Add this font to our known physical fonts try { org.docx4j.fonts.PhysicalFonts.addPhysicalFont(new java.net.URL("file:" + path)); // This needs to be done before populateFontMappings, // otherwise this font will be ignored, and references // to it mapped to some substitute font! } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } }