001: /*
002: *******************************************************************************
003: * Copyright (C) 1998-2004, International Business Machines Corporation and *
004: * others. All Rights Reserved. *
005: *******************************************************************************
006: *
007: * Created on Dec 3, 2003
008: *
009: *******************************************************************************
010: */
011: package com.ibm.icu.dev.tool.layout;
012:
013: import java.io.IOException;
014: import java.io.PrintWriter;
015: import java.io.Writer;
016:
017: import com.ibm.icu.text.UTF16;
018: import com.ibm.icu.impl.Utility;
019:
020: public class LigatureTree {
021: static class Lignode {
022: int target;
023: int ligature = -1;
024: Lignode[] subnodes = null;
025:
026: Lignode() {
027: target = -1;
028: }
029:
030: Lignode(int target) {
031: this .target = target;
032: }
033:
034: boolean isMatch() {
035: return ligature != -1;
036: }
037:
038: int getLigature() {
039: return ligature;
040: }
041:
042: Lignode subnode(int c) {
043: if (subnodes != null) {
044: int len = subnodes.length;
045:
046: if (c <= subnodes[len - 1].target) {
047: for (int i = 0; i < len; i += 1) {
048: int t = subnodes[i].target;
049:
050: if (t > c) {
051: return null;
052: }
053:
054: if (t == c) {
055: return subnodes[i];
056: }
057: }
058: }
059: }
060:
061: return null;
062: }
063:
064: String ligatureString(int[] chars) {
065: StringBuffer result = new StringBuffer();
066: int len = chars.length - 1;
067:
068: for (int i = 0; i < len; i += 1) {
069: if (i > 0) {
070: result.append(" + ");
071: }
072:
073: result.append(Utility.hex(chars[i], 6));
074: }
075:
076: result.append(" => " + Utility.hex(chars[len], 6));
077:
078: return result.toString();
079: }
080:
081: void insert(int[] chars, int index) {
082: int c = chars[index];
083: int len = chars.length;
084:
085: if (len == index + 1) {
086: if (ligature != -1) {
087: System.out.println("ignoring ligature "
088: + ligatureString(chars) + ": already have "
089: + Utility.hex(ligature, 6));
090: } else {
091: ligature = c;
092: }
093:
094: return;
095: }
096:
097: if (subnodes == null) {
098: subnodes = new Lignode[1];
099: subnodes[0] = new Lignode(c);
100: subnodes[0].insert(chars, index + 1);
101: } else {
102: int i;
103:
104: for (i = 0; i < subnodes.length; i += 1) {
105: int t = subnodes[i].target;
106:
107: if (t == c) {
108: subnodes[i].insert(chars, index + 1);
109: return;
110: } else if (t > c) {
111: break;
112: }
113: }
114:
115: Lignode[] nnodes = new Lignode[subnodes.length + 1];
116:
117: if (i > 0) {
118: System.arraycopy(subnodes, 0, nnodes, 0, i);
119: }
120:
121: nnodes[i] = new Lignode(c);
122:
123: if (i < subnodes.length) {
124: System.arraycopy(subnodes, i, nnodes, i + 1,
125: subnodes.length - i);
126: }
127:
128: subnodes = nnodes;
129:
130: subnodes[i].insert(chars, index + 1);
131: }
132: }
133:
134: public void walk(TreeWalker walker) {
135: if (target != -1) {
136: walker.down(target);
137: }
138:
139: if (subnodes != null) {
140: for (int i = 0; i < subnodes.length; i += 1) {
141: subnodes[i].walk(walker);
142: }
143: }
144:
145: if (ligature != -1) {
146: walker.ligature(ligature);
147: }
148:
149: walker.up();
150: }
151:
152: static final String ind = " ";
153:
154: /*
155: * Write debugging information to w, starting at the provided indentation level.
156: */
157: public void dump(Writer w, int indent) {
158: String tab = ind.substring(0, Math
159: .min(indent, ind.length()));
160:
161: try {
162: w.write(tab);
163: if (target != -1) {
164: w.write(Utility.hex(target, 6));
165: }
166:
167: if (ligature != -1) {
168: w.write(" --> ");
169: w.write(Utility.hex(ligature, 6));
170: }
171:
172: w.write("\n");
173:
174: if (subnodes != null) {
175: w.write(tab);
176: w.write("{\n");
177: indent += 4;
178:
179: for (int i = 0; i < subnodes.length; i += 1) {
180: subnodes[i].dump(w, indent);
181: }
182:
183: w.write(tab);
184: w.write("}\n");
185: }
186: } catch (IOException e) {
187: System.out.println(e);
188: }
189: }
190:
191: }
192:
193: private Lignode root = new Lignode();
194:
195: public LigatureTree() {
196: // anything?
197: }
198:
199: private int[] toIntArray(String s) {
200: int count = UTF16.countCodePoint(s);
201: int[] result = new int[count];
202:
203: for (int i = 0; i < count; i += 1) {
204: result[i] = UTF16.charAt(s, i);
205: }
206:
207: return result;
208: }
209:
210: public void insert(String string) {
211: root.insert(toIntArray(string), 0);
212: }
213:
214: public void insert(int[] chars) {
215: root.insert(chars, 0);
216: }
217:
218: public void walk(TreeWalker walker) {
219: root.walk(walker);
220: walker.done();
221: }
222:
223: public void dump() {
224: PrintWriter pw = new PrintWriter(System.out);
225:
226: root.dump(pw, 0);
227: pw.flush();
228: }
229: }
|