package org.freehep.graphicsio.font.truetype;
import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Stack;
/**
* Data input for true type files. All methods are named as the data formats in
* the true type specification.
*
* @author Simon Fischer
* @version $Id: TTFInput.java,v 1.5 2009-08-17 21:44:45 murkle Exp $
*/
public abstract class TTFInput {
private Stack filePosStack = new Stack();
private int tempFlags;
// --------------- IO ---------------
public abstract void seek(long offset) throws IOException;
abstract long getPointer() throws IOException;
public void pushPos() throws IOException {
filePosStack.push(new Long(getPointer()));
}
public void popPos() throws IOException {
seek(((Long) filePosStack.pop()).longValue());
}
// ---------- Simple Data Types --------------
public abstract int readRawByte() throws IOException;
public abstract int readByte() throws IOException;
public abstract short readShort() throws IOException;
public abstract int readUShort() throws IOException;
public abstract long readULong() throws IOException;
public abstract int readLong() throws IOException;
public abstract byte readChar() throws IOException;
public final short readFWord() throws IOException {
return readShort();
}
public final int readUFWord() throws IOException {
return readUShort();
}
public final double readFixed() throws IOException {
int major = readShort();
int minor = readShort();
return major + minor / 16384d;
}
public final double readF2Dot14() throws IOException {
int major = readByte();
int minor = readByte();
int fraction = minor + ((major & 0x3f) << 8);
int mantissa = major >> 6;
if (mantissa >= 2) {
mantissa -= 4;
}
return mantissa + fraction / 16384d;
}
// ------------------------------------------------------------
public final void checkShortZero() throws IOException {
if (readShort() != 0) {
System.err.println("Reserved bit should be 0.");
}
}
public static final boolean checkZeroBit(int b, int bit, String name)
throws IOException {
if (flagBit(b, bit)) {
System.err
.println("Reserved bit " + bit + " in " + name + " not 0.");
return false;
}
return true;
}
// ---------------- Flags --------------------
/**
* Reads unsigned short flags into a temporary variable which can be queried
* using the flagBit method.
*/
public void readUShortFlags() throws IOException {
tempFlags = readUShort();
}
/**
* Reads byte flags into a temporary variable which can be queried using the
* flagBit method.
*/
public void readByteFlags() throws IOException {
tempFlags = readByte();
}
public boolean flagBit(int bit) {
return flagBit(tempFlags, bit);
}
public static boolean flagBit(int b, int bit) {
return (b & (1 << bit)) > 0;
}
// ---------------- Arrays -------------------
public abstract void readFully(byte[] b) throws IOException;
public int[] readFFFFTerminatedUShortArray() throws IOException {
List values = new LinkedList();
int ushort = -1;
do {
ushort = readUShort();
values.add(Integer.valueOf(ushort));
} while (ushort != 0xFFFF);
int[] shorts = new int[values.size()];
Iterator i = values.iterator();
int j = 0;
while (i.hasNext()) {
shorts[j++] = ((Integer) i.next()).intValue();
}
return shorts;
}
public int[] readUShortArray(int n) throws IOException {
int[] temp = new int[n];
for (int i = 0; i < temp.length; i++) {
temp[i] = readUShort();
}
return temp;
}
public short[] readShortArray(int n) throws IOException {
short[] temp = new short[n];
for (int i = 0; i < temp.length; i++) {
temp[i] = readShort();
}
return temp;
}
}