2
*******************************************************************************
3
* Copyright (C) 1998-2010, International Business Machines Corporation and *
4
* others. All Rights Reserved. *
5
*******************************************************************************
7
* Created on Dec 3, 2003
9
*******************************************************************************
11
package com.ibm.icu.dev.tool.layout;
13
import java.util.Vector;
15
import com.ibm.icu.impl.Utility;
17
public class ClassTable implements LookupSubtable
19
static class ClassEntry
24
public ClassEntry(int glyphID, int classID)
26
this.glyphID = glyphID;
27
this.classID = classID;
30
public int getGlyphID()
35
public int getClassID()
40
public int compareTo(ClassEntry that)
42
return this.glyphID - that.glyphID;
46
// Straight insertion sort from Knuth vol. III, pg. 81
48
public static void sort(ClassEntry[] table, Vector unsorted)
50
for (int e = 0; e < table.length; e += 1) {
52
ClassEntry v = (ClassEntry) unsorted.elementAt(e);
54
for (i = e - 1; i >= 0; i -= 1) {
55
if (v.compareTo(table[i]) >= 0) {
59
table[i + 1] = table[i];
66
public static int search(ClassEntry[] table, int glyphID)
68
int log2 = Utility.highBit(table.length);
69
int power = 1 << log2;
70
int extra = table.length - power;
74
if (table[extra].glyphID <= glyphID) {
78
while (probe > (1 << 0)) {
81
if (table[index + probe].glyphID <= glyphID) {
86
if (table[index].glyphID == glyphID) {
94
static class ClassRangeRecord
96
private int startGlyphID;
97
private int endGlyphID;
100
public ClassRangeRecord(int startGlyphID, int endGlyphID, int classID)
102
this.startGlyphID = startGlyphID;
103
this.endGlyphID = endGlyphID;
104
this.classID = classID;
107
public void write(OpenTypeTableWriter writer)
109
System.out.print(Utility.hex(startGlyphID, 6));
110
System.out.print(" - ");
111
System.out.print(Utility.hex(endGlyphID, 6));
112
System.out.print(": ");
113
System.out.println(classID);
115
writer.writeData(startGlyphID);
116
writer.writeData(endGlyphID);
117
writer.writeData(classID);
121
private Vector classMap;
122
private ClassEntry[] classTable;
123
private int snapshotSize;
127
this.classMap = new Vector();
128
this.classTable = null;
129
this.snapshotSize = -1;
133
public void addMapping(int charID, int classID)
135
ClassEntry entry = new ClassEntry(charID, classID);
137
classMap.addElement(entry);
140
public void addMapping(int startCharID, int endCharID, int classID)
142
for (int charID = startCharID; charID <= endCharID; charID += 1) {
143
addMapping(charID, classID);
147
public int getGlyphClassID(int glyphID)
149
int index = ClassEntry.search(classTable, glyphID);
152
return classTable[index].getClassID();
158
public void snapshot()
160
if (snapshotSize != classMap.size()) {
161
snapshotSize = classMap.size();
162
classTable = new ClassEntry[snapshotSize];
164
ClassEntry.sort(classTable, classMap);
168
public void writeClassTable(OpenTypeTableWriter writer)
172
Vector classRanges = new Vector();
175
while (startIndex < classTable.length) {
176
int startID = classTable[startIndex].getGlyphID();
177
int classID = classTable[startIndex].getClassID();
178
int nextID = startID;
182
for (endIndex = startIndex; endIndex < classTable.length; endIndex += 1) {
183
if (classTable[endIndex].getGlyphID() != nextID ||
184
classTable[endIndex].getClassID() != classID) {
193
ClassRangeRecord range = new ClassRangeRecord(startID, endID, classID);
195
classRanges.addElement(range);
198
startIndex = endIndex;
201
writer.writeData(2); // table format = 2 (class ranges)
202
writer.writeData(classRanges.size()); // class range count
204
for (int i = 0; i < classRanges.size(); i += 1) {
205
ClassRangeRecord range = (ClassRangeRecord) classRanges.elementAt(i);
211
public void writeLookupSubtable(OpenTypeTableWriter writer)
213
int singleSubstitutionsBase = writer.getOutputIndex();
214
int coverageTableIndex;
218
writer.writeData(2); // format 2: Specified output glyph indices
219
coverageTableIndex = writer.getOutputIndex();
220
writer.writeData(0); // offset to coverage table (fixed later)
221
writer.writeData(classTable.length); // number of glyphIDs in substitution array
223
for (int i = 0; i < classTable.length; i += 1) {
224
writer.writeData(classTable[i].getClassID());
227
writer.fixOffset(coverageTableIndex, singleSubstitutionsBase);
229
writer.writeData(classTable.length);
231
for (int i = 0; i < classTable.length; i += 1) {
232
writer.writeData(classTable[i].getGlyphID());
b'\\ No newline at end of file'