Browse Source

added logging to the font converter

fixed (possibly) a problem where certain fonts
had a range value for the last character causing it to try to get invalid info
also handles the lack of support for non-unicode cmap tables better


git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@195135 13f79535-47bb-0310-9956-ffa450edef68
tags/Alt-Design-integration-base
Keiron Liddle 22 years ago
parent
commit
ba2073f0ca

+ 0
- 1
src/org/apache/fop/fonts/FontFileReader.java View File

@@ -69,7 +69,6 @@ public class FontFileReader {
ins.close();
}


/**
* Set current file position to offset
*/

+ 99
- 84
src/org/apache/fop/fonts/TTFFile.java View File

@@ -11,6 +11,9 @@ import java.util.Iterator;
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
@@ -22,7 +25,9 @@ public class TTFFile {
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;
@@ -67,6 +72,10 @@ public class TTFFile {
int ansiWidth[];
HashMap ansiIndex;

public void setLogger(Logger l) {
log = l;
}

/**
* Position inputstream to position indicated
* in the dirtab offset + offset
@@ -75,7 +84,7 @@ public class TTFFile {
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;
}

@@ -122,7 +131,7 @@ public class TTFFile {
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
@@ -133,15 +142,16 @@ public class TTFFile {
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;
}

@@ -150,7 +160,7 @@ public class TTFFile {
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();
@@ -158,12 +168,12 @@ public class TTFFile {
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];
@@ -196,10 +206,10 @@ public class TTFFile {
// 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++) {

@@ -209,7 +219,9 @@ public class TTFFile {

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)
@@ -233,22 +245,22 @@ public class TTFFile {
(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 {

@@ -257,7 +269,7 @@ public class TTFFile {
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);

@@ -266,7 +278,7 @@ public class TTFFile {
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);

@@ -285,14 +297,14 @@ public class TTFFile {
}
}

/*
* 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) {
@@ -320,8 +332,8 @@ public class TTFFile {
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 {
@@ -361,19 +373,19 @@ public class TTFFile {
* 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();
@@ -383,11 +395,17 @@ public class TTFFile {
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() {
@@ -445,8 +463,12 @@ public class TTFFile {
}

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;
@@ -457,7 +479,7 @@ public class TTFFile {
ttfFile.printStuff();

} catch (IOException ioe) {
System.out.println(ioe.toString());
log.error("problem reading font: " + ioe.toString(), ioe);
}
}

@@ -582,7 +604,7 @@ public class TTFFile {

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]);
@@ -631,7 +653,7 @@ public class TTFFile {

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);
}

/**
@@ -647,16 +669,15 @@ public class TTFFile {
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) {
@@ -687,16 +708,16 @@ public class TTFFile {

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;
@@ -708,13 +729,12 @@ public class TTFFile {
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());
}
@@ -725,10 +745,10 @@ public class TTFFile {
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];
}
}
@@ -736,10 +756,10 @@ public class TTFFile {
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);
}
}

@@ -812,7 +832,7 @@ public class TTFFile {
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));
}
}

@@ -829,7 +849,7 @@ public class TTFFile {
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();
@@ -843,7 +863,7 @@ public class TTFFile {
// 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:
@@ -942,7 +962,7 @@ public class TTFFile {
}
}
}
// System.out.println(kerningTab.toString());
// log.debug(kerningTab.toString());

// Create winAnsiEncoded kerning table

@@ -995,8 +1015,7 @@ public class TTFFile {
* @ 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)) {
@@ -1011,11 +1030,9 @@ public class TTFFile {
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;
@@ -1032,11 +1049,9 @@ public class TTFFile {
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

+ 32
- 13
src/org/apache/fop/fonts/apps/TTFReader.java View File

@@ -16,6 +16,9 @@ import java.util.HashMap;
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.
@@ -24,9 +27,13 @@ import java.util.Iterator;
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
@@ -107,11 +114,22 @@ public class TTFReader {
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");
@@ -145,18 +163,18 @@ public class TTFReader {
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.");

}
@@ -171,12 +189,15 @@ public class TTFReader {
*/
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;
@@ -192,8 +213,7 @@ public class TTFReader {
* @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
@@ -217,8 +237,7 @@ public class TTFReader {
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");

Loading…
Cancel
Save