import java.util.HashMap;
import java.util.ArrayList;
+import org.apache.avalon.framework.logger.ConsoleLogger;
+import org.apache.avalon.framework.logger.Logger;
+
/**
* Reads a TrueType file or a TrueType Collection.
* The TrueType spec can be found at the Microsoft
static final int MAX_CHAR_CODE = 255;
static final int ENC_BUF_SIZE = 1024;
- static String encoding = "WinAnsiEncoding"; // Deafult encoding
+ private Logger log;
+
+ static String encoding = "WinAnsiEncoding"; // Default encoding
short firstChar = 0;
boolean is_embeddable = true;
boolean hasSerifs = true;
int ansiWidth[];
HashMap ansiIndex;
+ public void setLogger(Logger l) {
+ log = l;
+ }
+
/**
* Position inputstream to position indicated
* in the dirtab offset + offset
long offset) throws IOException {
TTFDirTabEntry dt = (TTFDirTabEntry)dirTabs.get(name);
if (dt == null) {
- System.out.println("Dirtab " + name + " not found.");
+ log.error("Dirtab " + name + " not found.");
return;
}
int num_cmap = in.readTTFUShort(); // Number of cmap subtables
long cmap_unioffset = 0;
- // System.out.println(num_cmap+" cmap tables");
+ log.info(num_cmap+" cmap tables");
/*
* Read offset for all tables
int cmap_eid = in.readTTFUShort();
long cmap_offset = in.readTTFULong();
- // System.out.println("Platform ID: "+cmap_pid+
- // " Encoding: "+cmap_eid);
+ log.debug("Platform ID: "+cmap_pid+
+ " Encoding: "+cmap_eid);
if (cmap_pid == 3 && cmap_eid == 1)
cmap_unioffset = cmap_offset;
}
if (cmap_unioffset <= 0) {
- System.out.println("Unicode cmap table not present");
+ log.fatalError("Unicode cmap table not present");
+ log.fatalError("Unsupported format: Aborting");
return false;
}
int cmap_format = in.readTTFUShort();
int cmap_length = in.readTTFUShort();
- // System.out.println("CMAP format: "+cmap_format);
+ log.info("CMAP format: "+cmap_format);
if (cmap_format == 4) {
in.skip(2); // Skip version number
int cmap_segCountX2 = in.readTTFUShort();
int cmap_entrySelector = in.readTTFUShort();
int cmap_rangeShift = in.readTTFUShort();
- /*
- * System.out.println("segCountX2 : "+cmap_segCountX2);
- * System.out.println("searchRange : "+cmap_searchRange);
- * System.out.println("entrySelector: "+cmap_entrySelector);
- * System.out.println("rangeShift : "+cmap_rangeShift);
- */
+
+ log.debug("segCountX2 : "+cmap_segCountX2);
+ log.debug("searchRange : "+cmap_searchRange);
+ log.debug("entrySelector: "+cmap_entrySelector);
+ log.debug("rangeShift : "+cmap_rangeShift);
+
int cmap_endCounts[] = new int[cmap_segCountX2 / 2];
int cmap_startCounts[] = new int[cmap_segCountX2 / 2];
// and fill in the cmaps ArrayList
for (int i = 0; i < cmap_startCounts.length; i++) {
- /*
- * System.out.println(i+ ": "+cmap_startCounts[i]+
- * " - "+cmap_endCounts[i]);
- */
+
+ log.debug(i+ ": "+cmap_startCounts[i]+
+ " - "+cmap_endCounts[i]);
+
for (int j = cmap_startCounts[i]; j <= cmap_endCounts[i];
j++) {
if (mtxPtr < mtx_tab.length) {
int glyphIdx;
- if (cmap_rangeOffsets[i] != 0) {
+ // the last character 65535 = .notdef
+ // may have a range offset
+ if (cmap_rangeOffsets[i] != 0 && j != 65535) {
int glyphOffset =
glyphIdArrayOffset
+ ((cmap_rangeOffsets[i] / 2) + (j - cmap_startCounts[i]) + (i) - cmap_segCountX2 / 2)
(Integer)e.next();
ansiWidth[aIdx.intValue()] =
mtx_tab[glyphIdx].wx;
- /*
- * System.out.println("Added width "+
- * mtx_tab[glyphIdx].wx +
- * " uni: " + j +
- * " ansi: " + aIdx.intValue());
- */
+
+ log.debug("Added width "+
+ mtx_tab[glyphIdx].wx +
+ " uni: " + j +
+ " ansi: " + aIdx.intValue());
+
}
}
- /*
- * System.out.println("Idx: "+
- * glyphIdx +
- * " Delta: " + cmap_deltas[i]+
- * " Unicode: " + j +
- * " name: " +
- * mtx_tab[glyphIdx].name);
- */
+
+ log.debug("Idx: "+
+ glyphIdx +
+ " Delta: " + cmap_deltas[i]+
+ " Unicode: " + j +
+ " name: " +
+ mtx_tab[glyphIdx].name);
+
} else {
if (glyphIdx < mtx_tab.length)
mtx_tab[glyphIdx].unicodeIndex.add(new Integer(j));
else
- System.out.println("Glyph " + glyphIdx
+ log.debug("Glyph " + glyphIdx
+ " out of range: "
+ mtx_tab.length);
if (glyphIdx < mtx_tab.length)
mtx_tab[glyphIdx].unicodeIndex.add(new Integer(j));
else
- System.out.println("Glyph " + glyphIdx
+ log.debug("Glyph " + glyphIdx
+ " out of range: "
+ mtx_tab.length);
}
}
- /*
- * System.out.println("IIdx: "+
- * mtxPtr +
- * " Delta: " + cmap_deltas[i]+
- * " Unicode: " + j +
- * " name: " +
- * mtx_tab[(j+cmap_deltas[i]) & 0xffff].name);
- */
+
+ log.debug("IIdx: "+
+ mtxPtr +
+ " Delta: " + cmap_deltas[i]+
+ " Unicode: " + j +
+ " name: " +
+ mtx_tab[(j+cmap_deltas[i]) & 0xffff].name);
+
}
if (glyphIdx < mtx_tab.length) {
if (mtx_tab[glyphIdx].unicodeIndex.size() < 2) {
if (mtx_tab[i].index > max)
max = mtx_tab[i].index;
}
- System.out.println("Min: " + min);
- System.out.println("Max: " + max);
+ log.info("Min: " + min);
+ log.info("Max: " + max);
}
public void readFont(FontFileReader in) throws IOException {
* The name of the font to read data for must be supplied,
* else the name is ignored
*/
- public void readFont(FontFileReader in, String name) throws IOException {
+ public boolean readFont(FontFileReader in, String name) throws IOException {
/*
* Check if TrueType collection, and that the name
* exists in the collection
*/
- if (!checkTTC(in, name, true))
+ if (!checkTTC(in, name))
throw new IOException("Failed to read font");
readDirTabs(in);
readFontHeader(in);
getNumGlyphs(in);
- System.out.println("Number of glyphs in font: " + nglyphs);
+ log.info("Number of glyphs in font: " + nglyphs);
readHorizontalHeader(in);
readHorizontalMetrics(in);
initAnsiWidths();
readGlyf(in);
readName(in);
readPCLT(in);
- readCMAP(in); // Read cmap table and fill in ansiwidths
- createCMaps(); // Create cmaps for bfentries
+ // Read cmap table and fill in ansiwidths
+ boolean valid = readCMAP(in);
+ if(!valid) {
+ return false;
+ }
+ // Create cmaps for bfentries
+ createCMaps();
// print_max_min();
readKerning(in);
+ return true;
}
private void createCMaps() {
}
public static void main(String[] args) {
+ int level = ConsoleLogger.LEVEL_WARN;
+ Logger log = new ConsoleLogger(level);
try {
TTFFile ttfFile = new TTFFile();
+ ttfFile.setLogger(log);
+
FontFileReader reader = new FontFileReader(args[0]);
String name = null;
ttfFile.printStuff();
} catch (IOException ioe) {
- System.out.println(ioe.toString());
+ log.error("problem reading font: " + ioe.toString(), ioe);
}
}
dirTabs = new HashMap();
TTFDirTabEntry[] pd = new TTFDirTabEntry[ntabs];
- // System.out.println("Reading " + ntabs + " dir tables");
+ log.debug("Reading " + ntabs + " dir tables");
for (int i = 0; i < ntabs; i++) {
pd[i] = new TTFDirTabEntry();
dirTabs.put(pd[i].read(in), pd[i]);
in.skip(2 + 2 + 3 * 2 + 8 * 2);
nhmtx = in.readTTFUShort();
- // System.out.println("Number of horizontal metrics: " + nhmtx);
+ log.debug("Number of horizontal metrics: " + nhmtx);
}
/**
int mtx_size = (nglyphs > nhmtx) ? nglyphs : nhmtx;
mtx_tab = new TTFMtxEntry[mtx_size];
- // System.out.println("*** Widths array: \n");
+ log.debug("*** Widths array: \n");
for (int i = 0; i < mtx_size; i++)
mtx_tab[i] = new TTFMtxEntry();
for (int i = 0; i < nhmtx; i++) {
mtx_tab[i].wx = in.readTTFUShort();
mtx_tab[i].lsb = in.readTTFUShort();
- /*
- * System.out.println(" width["+i+"] = "+
- * get_ttf_funit(mtx_tab[i].wx)+";");
- */
+
+ log.debug(" width["+i+"] = "+
+ get_ttf_funit(mtx_tab[i].wx)+";");
}
if (nhmtx < mtx_size) {
in.skip(4 * 4);
- // System.out.println("Post format: "+post_format);
+ log.debug("Post format: "+post_format);
switch (post_format) {
case 0x00010000:
- // System.out.println("Postscript format 1");
+ log.debug("Postscript format 1");
for (i = 0; i < Glyphs.mac_glyph_names.length; i++) {
mtx_tab[i].name = Glyphs.mac_glyph_names[i];
}
break;
case 0x00020000:
- // System.out.println("Postscript format 2");
+ log.debug("Postscript format 2");
int numGlyphStrings = 0;
l = in.readTTFUShort(); // Num Glyphs
// short minIndex=256;
if (mtx_tab[i].index > 257)
numGlyphStrings++;
- // System.out.println("Post index: "+mtx_tab[i].index);
+ log.debug("Post index: "+mtx_tab[i].index);
}
// firstChar=minIndex;
ps_glyphs_buf = new String[numGlyphStrings];
- // System.out.println("Reading " + numGlyphStrings +
- // " glyphnames"+
- // ", was n num glyphs="+l);
+ log.debug("Reading " + numGlyphStrings +
+ " glyphnames" + ", was n num glyphs="+l);
for (i = 0; i < ps_glyphs_buf.length; i++) {
ps_glyphs_buf[i] = in.readTTFString(in.readTTFUByte());
}
Glyphs.mac_glyph_names[mtx_tab[i].index];
} else {
k = mtx_tab[i].index - NMACGLYPHS;
- /*
- * System.out.println(k+" i="+i+" mtx="+mtx_tab.length+
- * " ps="+ps_glyphs_buf.length);
- */
+
+ log.debug(k+" i="+i+" mtx="+mtx_tab.length+
+ " ps="+ps_glyphs_buf.length);
+
mtx_tab[i].name = ps_glyphs_buf[k];
}
}
break;
case 0x00030000:
// Postscript format 3 contains no glyph names
- System.out.println("Postscript format 3");
+ log.debug("Postscript format 3");
break;
default:
- System.out.println("Unknown Postscript format : " + post_format);
+ log.error("Unknown Postscript format : " + post_format);
}
}
mtx_tab[i].bbox[2] = mtx_tab[0].bbox[0];
mtx_tab[i].bbox[3] = mtx_tab[0].bbox[0];
}
- // System.out.println(mtx_tab[i].toString(this));
+ log.debug(mtx_tab[i].toString(this));
}
}
i += 2 * 2;
while (n-- > 0) {
- // System.out.println("Iteration: "+n);
+ // log.debug("Iteration: "+n);
in.seek_set(i);
platform_id = in.readTTFUShort();
encoding_id = in.readTTFUShort();
// if (k==1 || k==2 || k==0 || k==4 || k==6) {
in.seek_set(j + in.readTTFUShort());
String txt = in.readTTFString(l);
- // System.out.println(platform_id+" "+encoding_id+
+ // log.debug(platform_id+" "+encoding_id+
// " "+k+" "+txt);
switch (k) {
case 0:
}
}
}
- // System.out.println(kerningTab.toString());
+ // log.debug(kerningTab.toString());
// Create winAnsiEncoded kerning table
* @ return true if not collection or font name present, false
* otherwise
*/
- protected final boolean checkTTC(FontFileReader in, String name,
- boolean verbose) throws IOException {
+ protected final boolean checkTTC(FontFileReader in, String name) throws IOException {
String tag = in.readTTFString(4);
if ("ttcf".equals(tag)) {
dirOffsets[i] = in.readTTFULong();
}
- if (verbose) {
- System.out.println("This is a TrueType collection file with"
+ log.debug("This is a TrueType collection file with"
+ numDirectories + " fonts");
- System.out.println("Containing the following fonts: ");
- }
+ log.debug("Containing the following fonts: ");
// Read all the directories and name tables to check
// If the font exists - this is a bit ugly, but...
boolean found = false;
if (fullName.equals(name)) {
found = true;
dirTabOffset = dirOffsets[i];
- if (verbose)
- System.out.println("* " + fullName);
+ log.debug("* " + fullName);
} else {
- if (verbose)
- System.out.println(fullName);
+ log.debug(fullName);
}
// Reset names
import java.util.ArrayList;
import java.util.Iterator;
+import org.apache.avalon.framework.logger.ConsoleLogger;
+import org.apache.avalon.framework.logger.Logger;
+
/**
* A tool which reads TTF files and generates
* XML font metrics file for use in FOP.
public class TTFReader {
private boolean invokedStandalone = false;
+ private Logger log;
public TTFReader() {}
+ public void setLogger(Logger l) {
+ log = l;
+ }
/**
* Parse commandline arguments. put options in the HashMap and return
HashMap options = new HashMap();
String[] arguments = parseArguments(options, args);
+ int level = ConsoleLogger.LEVEL_INFO;
+ if (options.get("-d") != null) {
+ String lev = (String)options.get("-d");
+ if(lev.equals("DEBUG")) {
+ level = ConsoleLogger.LEVEL_DEBUG;
+ } else if(lev.equals("INFO")) {
+ level = ConsoleLogger.LEVEL_INFO;
+ }
+ }
+ Logger log = new ConsoleLogger(level);
+
TTFReader app = new TTFReader();
+ app.setLogger(log);
app.invokedStandalone = true;
- System.out.println("TTF Reader v1.1.1");
- System.out.println();
+ log.info("TTF Reader v1.1.2");
if (options.get("-enc") != null) {
String enc = (String)options.get("-enc");
ttcName);
if (isCid)
- System.out.println("Creating CID encoded metrics");
+ log.info("Creating CID encoded metrics");
else
- System.out.println("Creating WinAnsi encoded metrics");
+ log.info("Creating WinAnsi encoded metrics");
if (doc != null) {
app.writeFontXML(doc, arguments[1]);
}
if (ttf.isEmbeddable())
- System.out.println("This font contains no embedding license restrictions");
+ log.info("This font contains no embedding license restrictions");
else
- System.out.println("** Note: This font contains license retrictions for\n"
+ log.info("** Note: This font contains license retrictions for\n"
+ " embedding. This font shouldn't be embedded.");
}
*/
public TTFFile loadTTF(String fileName, String fontName) {
TTFFile ttfFile = new TTFFile();
+ ttfFile.setLogger(log);
try {
- System.out.println("Reading " + fileName + "...");
- System.out.println();
+ log.info("Reading " + fileName + "...");
FontFileReader reader = new FontFileReader(fileName);
- ttfFile.readFont(reader, fontName);
+ boolean supported = ttfFile.readFont(reader, fontName);
+ if(!supported) {
+ return null;
+ }
} catch (Exception e) {
e.printStackTrace();
return null;
* @param target The target filename for the XML file.
*/
public void writeFontXML(org.w3c.dom.Document doc, String target) {
- System.out.println("Writing xml font file " + target + "...");
- System.out.println();
+ log.info("Writing xml font file " + target + "...");
try {
OutputFormat format = new OutputFormat(doc); // Serialize DOM
public org.w3c.dom.Document constructFontXML(TTFFile ttf,
String fontName, String className, String resource, String file,
boolean isCid, String ttcName) {
- System.out.println("Creating xml font file...");
- System.out.println();
+ log.info("Creating xml font file...");
Document doc = new DocumentImpl();
Element root = doc.createElement("font-metrics");