ACIP->TMW and ACIP->Unicode now allow for Unicode escapes like K\u0F84. This means that the lack of support for ACIP's backslash, '\\', is mitigated because you can turn ACIP {K\} into ACIP {K\u0F84}.

Support for U+F021-U+F0FF, the PUA that the latest EWTS uses, is not provided.

Also, we've traded some speed for memory -- DuffCode now uses bytes, not ints.
This commit is contained in:
dchandler 2003-11-29 22:57:12 +00:00
parent dfaae4be93
commit ffd041e32c
2 changed files with 649 additions and 476 deletions

View file

@ -26,23 +26,27 @@ import org.thdl.util.ThdlDebug;
* An immutable representation of a Tibetan glyph in the * An immutable representation of a Tibetan glyph in the
* TibetanMachineWeb or TibetanMachine families of fonts. * TibetanMachineWeb or TibetanMachine families of fonts.
* *
* A DuffCode consists of a font number, a character, and a character * <p>A DuffCode consists of a font number, a character, and a
* number. A font identification and a character are sufficient to * character number. A font identification and a character are
* uniquely identify any TibetanMachineWeb or TibetanMachine glyph. * sufficient to uniquely identify any TibetanMachineWeb or
* TibetanMachine glyph. Whether a DuffCode represents a TM or TMW
* glyph is in the eye of the beholder -- such information is not
* intrinsically represented.
* *
* @author Edward Garrett, Tibetan and Himalayan Digital Library * @author Edward Garrett, Tibetan and Himalayan Digital Library
* @version 1.0 */ * @author David Chandler */
public final class DuffCode { public final class DuffCode {
/** /**
* the font number in which this glyph can be found, * the font number in which this glyph can be found, from 1
* from 1 (TibetanMachineWeb) to 10 (TibetanMachineWeb9). * (TibetanMachineWeb/TibetanMachine) ... to 5
*/ * (TibetanMachineWeb4/TibetanMachineSkt4) ... to 10
private int fontNum; * (TibetanMachineWeb9/[Invalid for TM family]). */
private byte fontNum;
/** /**
* the character value of this glyph, as an integer (that is, ordinal) * the character value of this glyph, as an integer (that is, ordinal)
*/ */
private int charNum; private byte charNum;
/** /**
* Called by {@link TibetanMachineWeb} to generate * Called by {@link TibetanMachineWeb} to generate
@ -53,32 +57,33 @@ public final class DuffCode {
* and the other is the ASCII code of the character. * and the other is the ASCII code of the character.
* *
* @param s the string to parse * @param s the string to parse
* @param leftToRight should be true if the first number is the font number, * @param leftToRight should be true if the first number is the font
* false if the second number is the font number * number, false if the second number is the font number */
*/ public DuffCode(String s, boolean leftToRight) {
public DuffCode(String s, boolean leftToRight) { StringTokenizer st = new StringTokenizer(s,",");
StringTokenizer st = new StringTokenizer(s,",");
try { try {
String val1 = st.nextToken(); String val1 = st.nextToken();
String val2 = st.nextToken(); String val2 = st.nextToken();
Integer num1 = new Integer(val1); Integer num1 = new Integer(val1);
Integer num2 = new Integer(val2); Integer num2 = new Integer(val2);
int n1val = num1.intValue();
int n2val = num2.intValue();
if (n1val > 255 || n1val < 0 || n2val > 255 || n2val < 0)
throw new NumberFormatException("FAILED ASSERTION: 0<=fontNum<=255 and 0<=charNum<=255");
if (leftToRight) { if (leftToRight) {
setFontNum(num1.intValue()); setFontNum(n1val);
charNum = num2.intValue(); setCharNum((char)n2val);
} } else {
else { setFontNum(n2val);
setFontNum(num2.intValue()); setCharNum((char)n1val);
charNum = num1.intValue(); }
} } catch (NumberFormatException e) {
}
catch (NumberFormatException e) {
ThdlDebug.noteIffyCode(); ThdlDebug.noteIffyCode();
} }
} }
/** /**
* Called to create DuffCodes on the fly * Called to create DuffCodes on the fly
@ -87,50 +92,61 @@ public final class DuffCode {
* @param font the identifying number of the font * @param font the identifying number of the font
* @param ch a character * @param ch a character
*/ */
public DuffCode(int font, char ch) { public DuffCode(int font, char ch) {
setFontNum(font); setFontNum(font);
charNum = (int)ch; setCharNum(ch);
} }
private void setFontNum(int font) { private void setFontNum(int font) {
if (!(font >= 1 && font <= 10)) if (!(font >= 1 && font <= 10))
throw new IllegalArgumentException("DuffCodes work with font numbers in the range [1, 5] or [1, 10]. This isn't in the range [1, 10]: " + font); throw new IllegalArgumentException("DuffCodes work with font numbers in the range [1, 5] or [1, 10]. This isn't in the range [1, 10]: " + font);
fontNum = font; fontNum = (byte)font;
} }
/** /**
* Gets the font number of this glyph. * Gets the font number of this glyph.
* @return the identifying font number for this DuffCode * @return the identifying font number for this DuffCode
*/ */
public int getFontNum() { public byte getFontNum() {
return fontNum; return fontNum;
} }
private void setCharNum(char x) {
short xs = (short)x;
if (xs >= 0 && xs <= 127)
charNum = (byte)xs;
else
charNum = (byte)(127-xs);
}
/** /**
* Gets the character for this glyph, as an integer. * Gets the character for this glyph, as an integer.
* @return the identifying character, converted to an * @return the identifying character, converted to an
* integer, for this DuffCode * integer, for this DuffCode
*/ */
public int getCharNum() { public short getCharNum() {
return charNum; if (charNum >= 0)
} return (short)charNum; // [0, 127]
else
return (short)(127-(short)charNum); // [128, 255]
}
/** /**
* Gets the character for this glyph. * Gets the character for this glyph.
* @return the identifying character for this DuffCode * @return the identifying character for this DuffCode
*/ */
public char getCharacter() { public char getCharacter() {
return (char)charNum; return (char)getCharNum();
} }
/** /**
* Assigns a hashcode based on the font number and character for this * Assigns a hashcode based on the font number and character for this
* glyph. * glyph.
* *
* @return the hash code for this object */ * @return the hash code for this object */
public int hashCode() { public int hashCode() {
return fontNum*256 + charNum; return ((int)fontNum)*256 + getCharNum();
} }
/** /**
* Evaluates two DuffCodes as equal iff their * Evaluates two DuffCodes as equal iff their
@ -139,40 +155,40 @@ public final class DuffCode {
* @param o the object (DuffCode) you want to compare * @param o the object (DuffCode) you want to compare
* @return true if this object is equal to o, false if not * @return true if this object is equal to o, false if not
*/ */
public boolean equals(Object o) { public boolean equals(Object o) {
if (o instanceof DuffCode) { if (o instanceof DuffCode) {
DuffCode dc = (DuffCode)o; DuffCode dc = (DuffCode)o;
if (fontNum == dc.fontNum && charNum == dc.charNum) if (fontNum == dc.fontNum && charNum == dc.charNum)
return true; return true;
} }
return false; return false;
} }
/** /**
* @return a string representation of this object */ * @return a string representation of this object */
public String toString() { public String toString() {
boolean[] err = new boolean[] { false }; boolean[] err = new boolean[] { false };
String wylie = TibetanMachineWeb.getWylieForGlyph(this, err); String wylie = TibetanMachineWeb.getWylieForGlyph(this, err);
if (err[0]) wylie = "undefined"; if (err[0]) wylie = "undefined";
return "<duffcode wylie=" return "<duffcode wylie="
+ wylie + " font=" + fontNum + wylie + " font=" + fontNum
+ " charNum=" + charNum + " character=" + " charNum=" + getCharNum() + " character="
+ new Character(getCharacter()).toString() + "/>"; + new Character(getCharacter()).toString() + "/>";
} }
/** /**
* @param TMW if this DuffCode represents a TMW glyph, not a TM glyph * @param TMW if this DuffCode represents a TMW glyph, not a TM glyph
* @return a string representation of this object that does not refer * @return a string representation of this object that does not refer
* to its Wylie representation (because the TMW->Wylie error messages * to its Wylie representation (because the TMW->Wylie error messages
* call upon this when there is none, and you don't want an infinite * call upon this when there is none, and you don't want an infinite
* recursion (manifesting as a StackOverflowError)) */ * recursion (manifesting as a StackOverflowError)) */
public String toString(boolean TMW) { public String toString(boolean TMW) {
boolean[] err = new boolean[] { false }; boolean[] err = new boolean[] { false };
return "<glyph font=" return "<glyph font="
+ (TMW + (TMW
? TibetanMachineWeb.tmwFontNames ? TibetanMachineWeb.tmwFontNames
: TibetanMachineWeb.tmFontNames)[fontNum] : TibetanMachineWeb.tmFontNames)[fontNum]
+ " charNum=" + charNum + " character=" + " charNum=" + getCharNum() + " character="
+ new Character(getCharacter()).toString() + "/>"; + new Character(getCharacter()).toString() + "/>";
} }
} }

File diff suppressed because it is too large Load diff