package com.opentrust.spi.pdf; import java.util.Iterator; import java.util.TreeMap; import com.opentrust.spi.crypto.ExceptionHandler; import com.opentrust.spi.logger.Channel; import com.opentrust.spi.logger.SPILogger; import com.spilowagie.text.pdf.BaseFont; import com.spilowagie.text.pdf.PRIndirectReference; import com.spilowagie.text.pdf.PdfArray; import com.spilowagie.text.pdf.PdfDictionary; import com.spilowagie.text.pdf.PdfName; import com.spilowagie.text.pdf.PdfReader; public class PDFFontHelper { private static SPILogger log = SPILogger.getLogger("PDFSIGN"); static TreeMap fontMap = new TreeMap(); static final PdfName F1 = new PdfName("FontFile"); static final PdfName F2 = new PdfName("FontFile2"); static final PdfName F3 = new PdfName("FontFile3"); public static void processResource(PdfDictionary resource) throws Exception { if (resource == null) return; PdfDictionary xos = (PdfDictionary) PdfReader.getPdfObject(resource.get(PdfName.XOBJECT)); if (xos != null) { for (Iterator it = xos.getKeys().iterator(); it.hasNext();) { PdfDictionary xo = (PdfDictionary) PdfReader.getPdfObject(xos.get((PdfName) it.next())); processResource((PdfDictionary) PdfReader.getPdfObject(xo.get(PdfName.RESOURCES))); } } PdfDictionary fonts = (PdfDictionary) PdfReader.getPdfObject(resource.get(PdfName.FONT)); if (fonts == null) return; for (Iterator it = fonts.getKeys().iterator(); it.hasNext();) { PdfName internalName = (PdfName)it.next(); log.debug(Channel.TECH, "processResource.Font=%1$s", internalName.toString()); PdfDictionary font = (PdfDictionary) PdfReader.getPdfObject(fonts.get(internalName)); String name = ((PdfName) PdfReader.getPdfObject(font.get(PdfName.BASEFONT))).toString(); log.debug(Channel.TECH, "basefont=%1$s", name); log.debug(Channel.TECH, "encoding=%1$s", PdfReader.getPdfObject(font.get(PdfName.ENCODING))); log.debug(Channel.TECH, "subType=%1$s", PdfReader.getPdfObject(font.get(PdfName.SUBTYPE))); if (name.length() > 8 && name.charAt(7) == '+') { name = name.substring(8) + " subset"; } else { name = name.substring(1); } PdfDictionary desc = (PdfDictionary) PdfReader.getPdfObject(font.get(PdfName.FONTDESCRIPTOR)); if (desc == null) { PdfArray arr = (PdfArray) PdfReader.getPdfObject(font.get(PdfName.DESCENDANTFONTS)); // For Type0 fonts log.debug(Channel.TECH, "array=%1$s", arr.getAsDict(0)); desc = (PdfDictionary) PdfReader.getPdfObject(arr.getAsDict(0).get(PdfName.FONTDESCRIPTOR)); } log.debug(Channel.TECH, "desc=%1$s", desc); if (desc != null) { log.debug(Channel.TECH, "fontname=%1$s", desc.get(PdfName.FONTNAME)); if (desc.get(F1) != null || desc.get(F2) != null || desc.get(F3) != null) name += " embedded"; } else name += " nofontdescriptor"; PdfName baseFontName = (PdfName) PdfReader.getPdfObject(fonts.get(PdfName.BASEFONT)); log.debug(Channel.TECH, "baseFontName=%1$s", baseFontName); PRIndirectReference iRef = (PRIndirectReference) fonts.get(internalName); log.debug(Channel.TECH, "iRef=%1$s", iRef); fontMap.put(name, BaseFont.createFont(iRef)); } } public static BaseFont getFirstBaseFont(PdfReader reader) { try { for (int k = 1; k <= reader.getNumberOfPages(); ++k) { PdfDictionary page = reader.getPageN(k); BaseFont bFont = getFirstBaseFont(page); if(bFont!=null) return bFont; } } catch (Exception e) { ExceptionHandler.handle(e); } return null; } private static BaseFont getFirstBaseFont(PdfDictionary page) { PdfDictionary resource = (PdfDictionary) PdfReader.getPdfObject(page.get(PdfName.RESOURCES)); if(resource!=null) { PdfDictionary fonts = (PdfDictionary) PdfReader.getPdfObject(resource.get(PdfName.FONT)); if (fonts == null) return null; for (Object iName : fonts.getKeys()) { PdfName internalName = (PdfName)iName; log.debug(Channel.TECH, "getFirstBaseFont.Font : %1$s", internalName); PdfDictionary font = (PdfDictionary) PdfReader.getPdfObject(fonts.get(internalName)); // PdfName subtype = (PdfName)reader.getPdfObject(font.get(PdfName.SUBTYPE)); // log.debug(Channel.TECH, "getFirstBaseFont.subType : %1$s", subtype); PRIndirectReference iRef = (PRIndirectReference) fonts.get(internalName); return BaseFont.createFont(iRef); //Voir pourquoi ne fonctionn pas quand on a par exemple un subtype=/Type1 } } return null; } }