| /* |
| ******************************************************************************* |
| * Copyright (C) 1998-2010, International Business Machines Corporation and * |
| * others. All Rights Reserved. * |
| ******************************************************************************* |
| * |
| * Created on Dec 3, 2003 |
| * |
| ******************************************************************************* |
| */ |
| package com.ibm.icu.dev.tool.layout; |
| |
| |
| import java.io.IOException; |
| import java.io.PrintWriter; |
| import java.io.Writer; |
| |
| import com.ibm.icu.impl.Utility; |
| import com.ibm.icu.text.UTF16; |
| |
| public class LigatureTree |
| { |
| static class Lignode |
| { |
| int target; |
| int ligature = -1; |
| Lignode[] subnodes = null; |
| |
| Lignode() |
| { |
| target = -1; |
| } |
| |
| Lignode(int target) |
| { |
| this.target = target; |
| } |
| |
| boolean isMatch() |
| { |
| return ligature != -1; |
| } |
| |
| int getLigature() |
| { |
| return ligature; |
| } |
| |
| Lignode subnode(int c) |
| { |
| if (subnodes != null) { |
| int len = subnodes.length; |
| |
| if (c <= subnodes[len - 1].target) { |
| for (int i = 0; i < len; i+= 1) { |
| int t = subnodes[i].target; |
| |
| if (t > c) { |
| return null; |
| } |
| |
| if (t == c) { |
| return subnodes[i]; |
| } |
| } |
| } |
| } |
| |
| return null; |
| } |
| |
| String ligatureString(int[] chars) |
| { |
| StringBuffer result = new StringBuffer(); |
| int len = chars.length - 1; |
| |
| for (int i = 0; i < len; i += 1) { |
| if (i > 0) { |
| result.append(" + "); |
| } |
| |
| result.append(Utility.hex(chars[i], 6)); |
| } |
| |
| result.append(" => " + Utility.hex(chars[len], 6)); |
| |
| return result.toString(); |
| } |
| |
| void insert(int[] chars, int index) |
| { |
| int c = chars[index]; |
| int len = chars.length; |
| |
| if (len == index + 1) { |
| if (ligature != -1) { |
| System.out.println("ignoring ligature " + ligatureString(chars) + |
| ": already have " + Utility.hex(ligature, 6)); |
| } else { |
| ligature = c; |
| } |
| |
| return; |
| } |
| |
| if (subnodes == null) { |
| subnodes = new Lignode[1]; |
| subnodes[0] = new Lignode(c); |
| subnodes[0].insert(chars, index + 1); |
| } else { |
| int i; |
| |
| for (i = 0; i < subnodes.length; i += 1) |
| { |
| int t = subnodes[i].target; |
| |
| if (t == c) { |
| subnodes[i].insert(chars, index + 1); |
| return; |
| } else if (t > c) { |
| break; |
| } |
| } |
| |
| Lignode[] nnodes = new Lignode[subnodes.length + 1]; |
| |
| if (i > 0) { |
| System.arraycopy(subnodes, 0, nnodes, 0, i); |
| } |
| |
| nnodes[i] = new Lignode(c); |
| |
| if (i < subnodes.length) { |
| System.arraycopy(subnodes, i, nnodes, i + 1, subnodes.length - i); |
| } |
| |
| subnodes = nnodes; |
| |
| subnodes[i].insert(chars, index + 1); |
| } |
| } |
| |
| public void walk(TreeWalker walker) |
| { |
| if (target != -1) { |
| walker.down(target); |
| } |
| |
| if (subnodes != null) { |
| for (int i = 0; i < subnodes.length; i += 1) |
| { |
| subnodes[i].walk(walker); |
| } |
| } |
| |
| if (ligature != -1) { |
| walker.ligature(ligature); |
| } |
| |
| walker.up(); |
| } |
| |
| static final String ind = " "; |
| |
| /* |
| * Write debugging information to w, starting at the provided indentation level. |
| */ |
| public void dump(Writer w, int indent) |
| { |
| String tab = ind.substring(0, Math.min(indent, ind.length())); |
| |
| try { |
| w.write(tab); |
| if (target != -1) { |
| w.write(Utility.hex(target, 6)); |
| } |
| |
| if (ligature != -1) |
| { |
| w.write(" --> "); |
| w.write(Utility.hex(ligature, 6)); |
| } |
| |
| w.write("\n"); |
| |
| if (subnodes != null) { |
| w.write(tab); |
| w.write("{\n"); |
| indent += 4; |
| |
| for (int i = 0; i < subnodes.length; i += 1) { |
| subnodes[i].dump(w, indent); |
| } |
| |
| w.write(tab); |
| w.write("}\n"); |
| } |
| } catch (IOException e) { |
| System.out.println(e); |
| } |
| } |
| |
| } |
| |
| private Lignode root = new Lignode(); |
| |
| public LigatureTree() |
| { |
| // anything? |
| } |
| |
| private int[] toIntArray(String s) |
| { |
| int count = UTF16.countCodePoint(s); |
| int[] result = new int[count]; |
| |
| for (int i = 0; i < count; i += 1) { |
| result[i] = UTF16.charAt(s, i); |
| } |
| |
| return result; |
| } |
| |
| public void insert(String string) |
| { |
| root.insert(toIntArray(string), 0); |
| } |
| |
| public void insert(int[] chars) |
| { |
| root.insert(chars, 0); |
| } |
| |
| public void walk(TreeWalker walker) |
| { |
| root.walk(walker); |
| walker.done(); |
| } |
| |
| public void dump() |
| { |
| PrintWriter pw = new PrintWriter(System.out); |
| |
| root.dump(pw, 0); |
| pw.flush(); |
| } |
| } |