2 *******************************************************************************
\r
3 * Copyright (C) 2002-2010, International Business Machines Corporation and *
\r
4 * others. All Rights Reserved. *
\r
5 *******************************************************************************
\r
8 package com.ibm.icu.dev.tool.layout;
\r
10 import java.util.Vector;
\r
12 import com.ibm.icu.text.UTF16;
\r
17 * To change the template for this generated type comment go to
\r
18 * Window>Preferences>Java>Code Generation>Code and Comments
\r
20 public class DecompTable implements LookupSubtable
\r
22 static class DecompEntry
\r
24 private int composed;
\r
25 private int[] decomp;
\r
27 DecompEntry(int composedChar, String decomposition)
\r
29 int decompCount = UTF16.countCodePoint(decomposition);
\r
31 composed = composedChar;
\r
32 decomp = new int[decompCount];
\r
36 for (int in = 0; in < decomposition.length(); in += UTF16.getCharCount(cp)) {
\r
37 cp = UTF16.charAt(decomposition, in);
\r
42 public int getComposedCharacter()
\r
47 public int[] getDecomposition()
\r
52 public int getDecompositionCount()
\r
54 return decomp.length;
\r
57 public int getDecomposedCharacter(int i)
\r
59 if (i >= 0 && i < decomp.length) {
\r
66 public int compareTo(DecompEntry that)
\r
68 return this.composed - that.composed;
\r
72 // Straight insertion sort from Knuth vol. III, pg. 81
\r
74 public static void sort(DecompEntry[] table, Vector decompVector)
\r
76 for (int j = 0; j < table.length; j += 1) {
\r
78 DecompEntry v = (DecompEntry) decompVector.elementAt(j);
\r
80 for (i = j - 1; i >= 0; i -= 1) {
\r
81 if (v.compareTo(table[i]) >= 0) {
\r
85 table[i + 1] = table[i];
\r
93 private Vector decompVector;
\r
94 private DecompEntry[] decompEntries;
\r
95 private int snapshotSize;
\r
97 public DecompTable()
\r
99 decompVector = new Vector();
\r
100 decompEntries = null;
\r
104 public void add(int composed, String decomposition)
\r
106 DecompEntry entry = new DecompEntry(composed, decomposition);
\r
108 decompVector.addElement(entry);
\r
111 public int getComposedCharacter(int i)
\r
113 if (i < 0 || i > decompEntries.length) {
\r
117 return decompEntries[i].getComposedCharacter();
\r
120 public int getDecompositionCount(int i)
\r
122 if (i < 0 || i > decompEntries.length) {
\r
126 return decompEntries[i].getDecompositionCount();
\r
129 public boolean hasEntries()
\r
131 return decompVector.size() > 0;
\r
134 private void snapshot()
\r
136 if (snapshotSize != decompVector.size()) {
\r
137 snapshotSize = decompVector.size();
\r
138 decompEntries = new DecompEntry[snapshotSize];
\r
139 DecompEntry.sort(decompEntries, decompVector);
\r
143 public void writeLookupSubtable(OpenTypeTableWriter writer)
\r
147 int multipleSubstitutionsBase = writer.getOutputIndex();
\r
148 int coverageTableIndex, sequenceOffsetIndex;
\r
149 int sequenceCount = decompEntries.length;
\r
151 writer.writeData(1); // format = 1
\r
153 coverageTableIndex = writer.getOutputIndex();
\r
154 writer.writeData(0); // coverage table offset (fixed later)
\r
156 writer.writeData(sequenceCount);
\r
158 sequenceOffsetIndex = writer.getOutputIndex();
\r
159 for (int s = 0; s < sequenceCount; s += 1) {
\r
160 writer.writeData(0); // offset to sequence table (fixed later);
\r
163 for (int s = 0; s < sequenceCount; s += 1) {
\r
164 DecompEntry entry = decompEntries[s];
\r
165 int decompCount = entry.getDecompositionCount();
\r
167 writer.fixOffset(sequenceOffsetIndex++, multipleSubstitutionsBase);
\r
169 writer.writeData(decompCount); // glyphCount
\r
171 for (int g = 0; g < decompCount; g += 1) {
\r
172 writer.writeData(entry.getDecomposedCharacter(g));
\r
176 // write a format 1 coverage table
\r
177 writer.fixOffset(coverageTableIndex, multipleSubstitutionsBase);
\r
178 writer.writeData(1); // format = 1
\r
179 writer.writeData(sequenceCount); // glyphCount
\r
181 for (int i = 0; i < sequenceCount; i += 1) {
\r
182 writer.writeData(decompEntries[i].getComposedCharacter());
\r