/*
* $Id$
*
* Copyright (C) 2003-2015 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.awt.font.truetype;
import java.io.IOException;
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$
*/
public abstract class TTFInput {
private Stack<Long> filePosStack = new Stack<Long>();
private int tempFlags;
public abstract TTFInput createSubInput(int offset, int length) throws IOException;
// --------------- 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());
}
public void close() throws IOException {
// Do nothing, overwrite where applicable
}
// ---------- 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;
} else {
return true;
}
}
// ---------------- Flags --------------------
/**
* Reads unsigned short flags into a temporary variable which can be queried using the flagBit
* method. *
*
* @throws IOException
*/
public void readUShortFlags() throws IOException {
tempFlags = readUShort();
}
/**
* Reads byte flags into a temporary variable which can be queried using the flagBit method. *
*
* @throws IOException
*/
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 {
final List<Integer> values = new LinkedList<Integer>();
int ushort = -1;
do {
ushort = readUShort();
values.add(new Integer(ushort));
} while (ushort != 0xFFFF);
int[] shorts = new int[values.size()];
int j = 0;
for (int v : values) {
shorts[j++] = v;
}
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;
}
}