| /* |
| * Licensed to the Apache Software Foundation (ASF) under one or more |
| * contributor license agreements. See the NOTICE file distributed with |
| * this work for additional information regarding copyright ownership. |
| * The ASF licenses this file to You under the Apache License, Version 2.0 |
| * (the "License"); you may not use this file except in compliance with |
| * the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| /* $Id$ */ |
| |
| package org.apache.fop.afp.apps; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.DataInputStream; |
| import java.io.File; |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.OutputStream; |
| import java.io.PrintStream; |
| |
| import org.apache.commons.io.HexDump; |
| import org.apache.commons.io.IOUtils; |
| import org.apache.commons.io.output.ByteArrayOutputStream; |
| |
| import org.apache.fop.afp.parser.MODCAParser; |
| import org.apache.fop.afp.parser.UnparsedStructuredField; |
| |
| /** |
| * This class represents a tool for extracting the Type 1 PFB file from an AFP outline font. |
| */ |
| public class FontPatternExtractor { |
| |
| private PrintStream printStream = System.out; |
| |
| /** |
| * Extracts the Type1 PFB file from the given AFP outline font. |
| * @param file the AFP file to read from |
| * @param targetDir the target directory where the PFB file is to be placed. |
| * @throws IOException if an I/O error occurs |
| */ |
| public void extract(File file, File targetDir) throws IOException { |
| InputStream in = new java.io.FileInputStream(file); |
| try { |
| MODCAParser parser = new MODCAParser(in); |
| ByteArrayOutputStream baout = new ByteArrayOutputStream(); |
| UnparsedStructuredField strucField; |
| while ((strucField = parser.readNextStructuredField()) != null) { |
| if (strucField.getSfTypeID() == 0xD3EE89) { |
| byte[] sfData = strucField.getData(); |
| println(strucField.toString()); |
| HexDump.dump(sfData, 0, printStream, 0); |
| baout.write(sfData); |
| } |
| } |
| |
| ByteArrayInputStream bin = new ByteArrayInputStream(baout.toByteArray()); |
| IOUtils.closeQuietly(baout); |
| DataInputStream din = new DataInputStream(bin); |
| long len = din.readInt() & 0xFFFFFFFFL; |
| println("Length: " + len); |
| if (din.skip(4) != 4) { //checksum |
| throw new IOException("premature EOF when skipping checksum"); |
| } |
| int tidLen = din.readUnsignedShort() - 2; |
| byte[] tid = new byte[tidLen]; |
| din.readFully(tid); |
| String filename = new String(tid, "ISO-8859-1"); |
| int asciiCount1 = countUSAsciiCharacters(filename); |
| String filenameEBCDIC = new String(tid, "Cp1146"); |
| int asciiCount2 = countUSAsciiCharacters(filenameEBCDIC); |
| println("TID: " + filename + " " + filenameEBCDIC); |
| |
| if (asciiCount2 > asciiCount1) { |
| //Haven't found an indicator if the name is encoded in EBCDIC or not |
| //so we use a trick. |
| filename = filenameEBCDIC; |
| } |
| if (!filename.toLowerCase().endsWith(".pfb")) { |
| filename = filename + ".pfb"; |
| } |
| println("Output filename: " + filename); |
| File out = new File(targetDir, filename); |
| |
| OutputStream fout = new java.io.FileOutputStream(out); |
| try { |
| IOUtils.copyLarge(din, fout); |
| } finally { |
| IOUtils.closeQuietly(fout); |
| } |
| |
| |
| } finally { |
| IOUtils.closeQuietly(in); |
| } |
| } |
| |
| private void println(String s) { |
| printStream.println(s); |
| } |
| |
| private void println() { |
| printStream.println(); |
| } |
| |
| private int countUSAsciiCharacters(String filename) { |
| int count = 0; |
| for (int i = 0, c = filename.length(); i < c; i++) { |
| if (filename.charAt(i) < 128) { |
| count++; |
| } |
| } |
| return count; |
| } |
| |
| /** |
| * Main method |
| * @param args the command-line arguments |
| */ |
| public static void main(String[] args) { |
| try { |
| FontPatternExtractor app = new FontPatternExtractor(); |
| |
| app.println("Font Pattern Extractor"); |
| app.println(); |
| |
| if (args.length > 0) { |
| String filename = args[0]; |
| File file = new File(filename); |
| |
| File targetDir = file.getParentFile(); |
| if (args.length > 1) { |
| targetDir = new File(args[1]); |
| targetDir.mkdirs(); |
| } |
| |
| app.extract(file, targetDir); |
| } else { |
| app.println("This tool tries to extract the PFB file from an AFP outline font."); |
| app.println(); |
| app.println("Usage: Java -cp ... " + FontPatternExtractor.class.getName() |
| + " <afp-font-file> [<target-dir>]"); |
| System.exit(-1); |
| } |
| |
| |
| } catch (Exception e) { |
| e.printStackTrace(); |
| System.exit(-1); |
| } |
| } |
| |
| } |