/** * create a new TrueTypeFont object based on a description of the font from the PDF file. If the * description happens to contain an in-line true-type font file (under key "FontFile2"), use the * true type font. Otherwise, parse the description for key information and use that to generate * an appropriate font. */ public TTFFont(String baseFont, PDFObject fontObj, PDFFontDescriptor descriptor) throws IOException { super(baseFont, fontObj, descriptor); String fontName = descriptor.getFontName(); PDFObject ttfObj = descriptor.getFontFile2(); // try { // byte[] fontData = ttfObj.getStream(); // java.io.FileOutputStream fis = new java.io.FileOutputStream("/tmp/" + fontName + ".ttf"); // fis.write(fontData); // fis.flush(); // fis.close(); // } catch (Exception ex) { // ex.printStackTrace(); // } if (ttfObj != null) { this.font = TrueTypeFont.parseFont(ttfObj.getStreamBuffer()); // read the units per em from the head table HeadTable head = (HeadTable) this.font.getTable("head"); this.unitsPerEm = head.getUnitsPerEm(); } else { this.font = null; } // System.out.println ("TTFFont: ttfObj: " + ttfObj + ", fontName: " + fontName); }
/** * Set the font * * @param fontdata the font data as a byte array */ protected void setFont(byte[] fontdata) throws FontFormatException, IOException { // System.out.println("Loading " + getBaseFont()); // FileOutputStream fos = new FileOutputStream("/tmp/" + getBaseFont() + ".ttf"); // fos.write(fontdata); // fos.close(); try { // read the true type information TrueTypeFont ttf = TrueTypeFont.parseFont(fontdata); // System.out.println(ttf.toString()); // get the cmap, post, and hmtx tables for later use this.cmapTable = (CmapTable) ttf.getTable("cmap"); this.postTable = (PostTable) ttf.getTable("post"); this.hmtxTable = (HmtxTable) ttf.getTable("hmtx"); // read the units per em from the head table HeadTable headTable = (HeadTable) ttf.getTable("head"); this.unitsPerEm = headTable.getUnitsPerEm(); /* Find out if we have the right info in our name table. * This is a hack because Java can only deal with fonts that * have a Microsoft encoded name in their name table (PlatformID 3). * We'll 'adjust' the font to add it if not, and take our chances * with our parsing, since it wasn't going to work anyway. */ NameTable nameTable = null; try { nameTable = (NameTable) ttf.getTable("name"); } catch (Exception ex) { System.out.println("Error reading name table for font " + getBaseFont() + ". Repairing!"); } boolean nameFixed = fixNameTable(ttf, nameTable); /* Figure out if we need to hack the CMap table. This might * be the case if we use characters that Java considers control * characters (0x9, 0xa and 0xd), that have to be re-mapped */ boolean cmapFixed = fixCMapTable(ttf, this.cmapTable); // use the parsed font instead of the original if (nameFixed || cmapFixed) { // System.out.println("Using fixed font!"); // System.out.println(ttf.toString()); fontdata = ttf.writeFont(); // FileOutputStream fos2 = new FileOutputStream("/tmp/" + getBaseFont() + ".fix"); // fos2.write(fontdata); // fos2.close(); } } catch (Exception ex) { System.out.println("Error parsing font : " + getBaseFont()); ex.printStackTrace(); } ByteArrayInputStream bais = new ByteArrayInputStream(fontdata); this.f = Font.createFont(Font.TRUETYPE_FONT, bais); bais.close(); }