blob: 478c7dcd727e9c544c5c008a9a8f769db77ae610 [file] [log] [blame]
/*
* 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);
}
}
}