blob: aeb6fb29f2bdfb5300776b32de425ecad321b43f [file] [log] [blame]
/*
*******************************************************************************
* 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();
}
}