/*
 * 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: FontPatternExtractor.java 1617052 2014-08-10 06:55:01Z gadams $ */

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.
/** * 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.
Params:
  • file – the AFP file to read from
  • targetDir – the target directory where the PFB file is to be placed.
Throws:
/** * 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
Params:
  • args – the command-line arguments
/** * 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); } } }