ICU-2649 initial port of Arabic and Hebrew ligature table builder to ICU4J, and merge w/ existing tools in com.ibm.icu.dev.tool.layout.

X-SVN-Rev: 14046
This commit is contained in:
Eric Mader 2003-12-09 01:18:12 +00:00
parent 648a43a3d8
commit 4e6e5b433f
27 changed files with 2544 additions and 277 deletions

View file

@ -0,0 +1,360 @@
/*
*******************************************************************************
* Copyright (C) 1998-2003, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
* Created on Dec 3, 2003
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/tool/layout/Attic/ArabicGSUBBuilder.java,v $
* $Date: 2003/12/09 01:18:11 $
* $Revision: 1.1 $
*
*******************************************************************************
*/
package com.ibm.icu.dev.tool.layout;
import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.lang.UCharacterCategory;
import com.ibm.icu.text.Normalizer;
import com.ibm.icu.text.Transliterator;
import com.ibm.icu.text.UnicodeSet;
import com.ibm.icu.text.UnicodeSetIterator;
import com.ibm.icu.text.UTF16;
public class ArabicGSUBBuilder
{
static public String convertString(int type, int ligature, String decomp, ClassTable isolClassTable)
{
int leftType = ArabicShaping.VALUE_NONE;
int rightType = ArabicShaping.VALUE_NONE;
switch (type) {
case UCharacter.DecompositionType.ISOLATED:
break;
case UCharacter.DecompositionType.FINAL:
rightType = ArabicShaping.VALUE_LEFT;
break;
case UCharacter.DecompositionType.INITIAL:
leftType = ArabicShaping.VALUE_RIGHT;
break;
case UCharacter.DecompositionType.MEDIAL:
rightType = ArabicShaping.VALUE_LEFT;
leftType = ArabicShaping.VALUE_RIGHT;
break;
default:
return decomp + UTF16.toString(ligature);
}
char[] chars = decomp.toCharArray();
ArabicShaping.shape(chars, leftType, rightType, isolClassTable);
return new String(chars) + UTF16.toString(ligature);
}
static void buildContextualForms(CharacterData data, ClassTable initClassTable, ClassTable mediClassTable,
ClassTable finaClassTable, ClassTable isolClassTable)
{
System.out.print("Finding contextual forms... ");
for (int i = 0; i < data.countRecords(); i += 1) {
CharacterData.Record record = data.getRecord(i);
String decomposition = record.getDecomposition();
if (decomposition != null && decomposition.length() == 1) {
int contextual = record.getCodePoint();
int isolated = UTF16.charAt(record.getDecomposition(), 0);
switch (record.getDecompositionType()) {
case UCharacter.DecompositionType.INITIAL:
initClassTable.addMapping(isolated, contextual);
break;
case UCharacter.DecompositionType.MEDIAL:
mediClassTable.addMapping(isolated, contextual);
break;
case UCharacter.DecompositionType.FINAL:
finaClassTable.addMapping(isolated, contextual);
break;
case UCharacter.DecompositionType.ISOLATED:
isolClassTable.addMapping(isolated, contextual);
break;
default:
// issue some error message?
break;
}
}
}
System.out.println("Done.");
}
static void buildLigatureTrees(CharacterData data, ClassTable isolClassTable,
LigatureTree contextualTree, LigatureTree cannonicalTree)
{
System.out.print("Building ligature trees... ");
for (int i = 0; i < data.countRecords(); i += 1) {
CharacterData.Record record = data.getRecord(i);
String decomposition = record.getDecomposition();
if (decomposition != null && decomposition.length() > 1) {
int ligature = record.getCodePoint();
int decompType = record.getDecompositionType();
switch (decompType) {
case UCharacter.DecompositionType.FINAL:
case UCharacter.DecompositionType.INITIAL:
case UCharacter.DecompositionType.MEDIAL:
case UCharacter.DecompositionType.ISOLATED:
contextualTree.insert(convertString(decompType, ligature, decomposition, isolClassTable));
break;
case UCharacter.DecompositionType.CANONICAL:
cannonicalTree.insert(decomposition + UTF16.toString(ligature));
break;
}
}
}
System.out.println("Done.");
}
static final int SIMPLE_GLYPH = 1;
static final int LIGATURE_GLYPH = 2;
static final int MARK_GLYPH = 3;
static final int COMPONENT_GLYPH = 4;
static final int categoryClassMap[] = {
0, // UNASSIGNED
SIMPLE_GLYPH, // UPPERCASE_LETTER
SIMPLE_GLYPH, // LOWERCASE_LETTER
SIMPLE_GLYPH, // TITLECASE_LETTER
SIMPLE_GLYPH, // MODIFIER_LETTER
SIMPLE_GLYPH, // OTHER_LETTER
MARK_GLYPH, // NON_SPACING_MARK
MARK_GLYPH, // ENCLOSING_MARK ??
MARK_GLYPH, // COMBINING_SPACING_MARK ??
SIMPLE_GLYPH, // DECIMAL_NUMBER
SIMPLE_GLYPH, // LETTER_NUMBER
SIMPLE_GLYPH, // OTHER_NUMBER;
0, // SPACE_SEPARATOR
0, // LINE_SEPARATOR
0, // PARAGRAPH_SEPARATOR
0, // CONTROL
0, // FORMAT
0, // PRIVATE_USE
0, // SURROGATE
SIMPLE_GLYPH, // DASH_PUNCTUATION
SIMPLE_GLYPH, // START_PUNCTUATION
SIMPLE_GLYPH, // END_PUNCTUATION
SIMPLE_GLYPH, // CONNECTOR_PUNCTUATION
SIMPLE_GLYPH, // OTHER_PUNCTUATION
SIMPLE_GLYPH, // MATH_SYMBOL;
SIMPLE_GLYPH, // CURRENCY_SYMBOL
SIMPLE_GLYPH, // MODIFIER_SYMBOL
SIMPLE_GLYPH, // OTHER_SYMBOL
SIMPLE_GLYPH, // INITIAL_PUNCTUATION
SIMPLE_GLYPH // FINAL_PUNCTUATION
};
static int getGlyphClass(CharacterData.Record record)
{
String decomp = record.getDecomposition();
if (decomp != null && decomp.length() > 1) {
return LIGATURE_GLYPH;
}
return categoryClassMap[record.getGeneralCategory()];
}
static ClassTable buildGlyphClassTable(CharacterData data)
{
System.out.print("Building glyph class table... ");
ClassTable classTable = new ClassTable();
for (int i = 0; i < data.countRecords(); i += 1) {
CharacterData.Record record = data.getRecord(i);
classTable.addMapping(record.getCodePoint(), getGlyphClass(record));
}
System.out.println("Done.");
return classTable;
}
private static void buildArabicTables(String fileName) {
// TODO: Might want to have the ligature table builder explicitly check for ligatures
// which start with space and tatweel rather than pulling them out here...
UnicodeSet arabicBlock = new UnicodeSet("[[\\p{block=Arabic}] & [[:Cf:][:Po:][:So:][:Mn:][:Nd:][:Lm:]]]");
UnicodeSet oddLigatures = new UnicodeSet("[\\uFC5E-\\uFC63\\uFCF2-\\uFCF4\\uFE70-\\uFE7F]");
UnicodeSet arabicLetters = new UnicodeSet("[\\p{Arabic}]");
CharacterData arabicData = CharacterData.factory(arabicLetters.addAll(arabicBlock).removeAll(oddLigatures));
ClassTable classTable = buildGlyphClassTable(arabicData);
ClassTable initClassTable = new ClassTable();
ClassTable mediClassTable = new ClassTable();
ClassTable finaClassTable = new ClassTable();
ClassTable isolClassTable = new ClassTable();
buildContextualForms(arabicData, initClassTable, mediClassTable, finaClassTable, isolClassTable);
isolClassTable.snapshot();
LigatureTree ccmpTree = new LigatureTree();
LigatureTree ligaTree = new LigatureTree();
buildLigatureTrees(arabicData, isolClassTable, ligaTree, ccmpTree);
LigatureTreeWalker ccmpWalker = new LigatureTreeWalker();
LigatureTreeWalker ligaWalker = new LigatureTreeWalker();
ccmpTree.walk(ccmpWalker);
ligaTree.walk(ligaWalker);
LookupList lookupList = new LookupList();
FeatureList featureList = new FeatureList();
ScriptList scriptList = new ScriptList();
Lookup ccmpLookup, initLookup, mediLookup, finaLookup, ligaLookup;
int ccmpLookupIndex, initLookupIndex, mediLookupIndex, finaLookupIndex, ligaLookupIndex;
ccmpLookup = new Lookup(Lookup.GSST_Ligature, 0);
ccmpLookup.addSubtable(ccmpWalker);
initLookup = new Lookup(Lookup.GSST_Single, 0);
initLookup.addSubtable(initClassTable);
mediLookup = new Lookup(Lookup.GSST_Single, 0);
mediLookup.addSubtable(mediClassTable);
finaLookup = new Lookup(Lookup.GSST_Single, 0);
finaLookup.addSubtable(finaClassTable);
ligaLookup = new Lookup(Lookup.GSST_Ligature, Lookup.LF_IgnoreMarks);
ligaLookup.addSubtable(ligaWalker);
ccmpLookupIndex = lookupList.addLookup(ccmpLookup);
initLookupIndex = lookupList.addLookup(initLookup);
mediLookupIndex = lookupList.addLookup(mediLookup);
finaLookupIndex = lookupList.addLookup(finaLookup);
ligaLookupIndex = lookupList.addLookup(ligaLookup);
featureList.addLookup("ccmp", ccmpLookupIndex);
featureList.addLookup("init", initLookupIndex);
featureList.addLookup("medi", mediLookupIndex);
featureList.addLookup("fina", finaLookupIndex);
featureList.addLookup("liga", ligaLookupIndex);
featureList.finalizeFeatureList();
scriptList.addFeature("arab", "(default)", featureList.getFeatureIndex("ccmp"));
scriptList.addFeature("arab", "(default)", featureList.getFeatureIndex("init"));
scriptList.addFeature("arab", "(default)", featureList.getFeatureIndex("medi"));
scriptList.addFeature("arab", "(default)", featureList.getFeatureIndex("fina"));
scriptList.addFeature("arab", "(default)", featureList.getFeatureIndex("liga"));
GSUBWriter gsubWriter = new GSUBWriter("Arabic", scriptList, featureList, lookupList);
GDEFWriter gdefWriter = new GDEFWriter("Arabic", classTable);
String[] includeFiles = {"LETypes.h", "ArabicShaping.h"};
LigatureModuleWriter writer = new LigatureModuleWriter();
writer.openFile(fileName);
writer.writeHeader(null, includeFiles);
writer.writeTable(gsubWriter);
writer.writeTable(gdefWriter);
writer.writeTrailer();
writer.closeFile();
}
private static void buildHebrewTables(String fileName)
{
UnicodeSet hebrewBlock = new UnicodeSet("[[\\p{block=Hebrew}] & [[:Cf:][:Po:][:So:][:Mn:][:Nd:][:Lm:]]]");
UnicodeSet oddLigatures = new UnicodeSet("[\\uFC5E-\\uFC63\\uFCF2-\\uFCF4\\uFE70-\\uFE7F]");
UnicodeSet hebrewLetters = new UnicodeSet("[\\p{Hebrew}]");
CharacterData hebrewData = CharacterData.factory(hebrewLetters.addAll(hebrewBlock).removeAll(oddLigatures));
ClassTable classTable = buildGlyphClassTable(hebrewData);
LigatureTree ligaTree = new LigatureTree();
buildLigatureTrees(hebrewData, null, null, ligaTree);
LigatureTreeWalker ligaWalker = new LigatureTreeWalker();
ligaTree.walk(ligaWalker);
LookupList lookupList = new LookupList();
FeatureList featureList = new FeatureList();
ScriptList scriptList = new ScriptList();
Lookup ligaLookup;
int ligaLookupIndex;
ligaLookup = new Lookup(Lookup.GSST_Ligature, 0);
ligaLookup.addSubtable(ligaWalker);
ligaLookupIndex = lookupList.addLookup(ligaLookup);
featureList.addLookup("liga", ligaLookupIndex);
featureList.finalizeFeatureList();
scriptList.addFeature("hebr", "(default)", featureList.getFeatureIndex("liga"));
GSUBWriter gsubWriter = new GSUBWriter("Hebrew", scriptList, featureList, lookupList);
GDEFWriter gdefWriter = new GDEFWriter("Hebrew", classTable);
String[] includeFiles = {"LETypes.h", "HebrewShaping.h"};
LigatureModuleWriter writer = new LigatureModuleWriter();
writer.openFile(fileName);
writer.writeHeader(null, includeFiles);
writer.writeTable(gsubWriter);
writer.writeTable(gdefWriter);
writer.writeTrailer();
writer.closeFile();
}
/*
* Conversion notes:
*
* Use a UnicodeSet of [\p{Arab}] to get all the Arabic letters. (Might want to
* subtract [\uFBE8\uFBE9] (Uighur Alef Maksura forms) and [\UFBF9-\UFBFB] Uighur
* ligatures which decompose to the same characters as the corresponding "normal"
* ones.)
*
* Use UCharacter.getType(ch) to get the general category. Values are defined in
* UCharacterCategory.
*
* Use (something like) [\p{DecompositonType=INITIAL}] to get initial, medial
* final (and isolated?) forms.
*
* Use the normalizer to decompose the characters: if the decomposition is
* a single letter, it's an initial, medial or final form, otherwise it's a
* ligature.
*
* Use ArabicShaping to convert the decomposed ligature back into shaped
* presentation forms. Need to add kashida's on the front and / or back to
* get it to generate the correct forms. (could add either a kashida or a
* non-joiner so that we never need to look at the first or last character)
*
* Can do contextual forms and ligatures in a single pass, since we have
* to actually normalize the character to figure out if it's a ligature or
* not. Also need the ligature-ness of the character to compute it's glyph
* class... might work to keep a class table which says contextual or ligature
* for each character. Build it while building contextual and ligature tables,
* then use it to generate the actual glyph class table... (this is backwards
* to how it's done now ;-)
*/
public static void main(String[] args)
{
buildArabicTables(args[0]);
buildHebrewTables(args[1]);
}
}

View file

@ -0,0 +1,127 @@
/*
*******************************************************************************
* Copyright (C) 1998-2003, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
* Created on Dec 3, 2003
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/tool/layout/ArabicShaping.java,v $
* $Date: 2003/12/09 01:18:11 $
* $Revision: 1.1 $
*
*******************************************************************************
*/
package com.ibm.icu.dev.tool.layout;
import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.lang.UProperty;
public class ArabicShaping {
// arabic shaping type code
// shaping bit masks
static final int MASK_SHAPE_RIGHT = 1; // if this bit set, shapes to right
static final int MASK_SHAPE_LEFT = 2; // if this bit set, shapes to left
static final int MASK_TRANSPARENT = 4; // if this bit set, is transparent (ignore other bits)
static final int MASK_NOSHAPE = 8; // if this bit set, don't shape this char, i.e. tatweel
// shaping values
public static final int VALUE_NONE = 0;
public static final int VALUE_RIGHT = MASK_SHAPE_RIGHT;
public static final int VALUE_LEFT = MASK_SHAPE_LEFT;
public static final int VALUE_DUAL = MASK_SHAPE_RIGHT | MASK_SHAPE_LEFT;
public static final int VALUE_TRANSPARENT = MASK_TRANSPARENT;
public static final int VALUE_NOSHAPE_DUAL = MASK_NOSHAPE | VALUE_DUAL;
public static final int VALUE_NOSHAPE_NONE = MASK_NOSHAPE;
public static int getShapeType(char ch)
{
int tt = UCharacter.getIntPropertyValue(ch, UProperty.JOINING_TYPE);
switch(tt) {
case UCharacter.JoiningType.JOIN_CAUSING:
return VALUE_NOSHAPE_DUAL;
case UCharacter.JoiningType.LEFT_JOINING:
return VALUE_LEFT;
case UCharacter.JoiningType.RIGHT_JOINING:
return VALUE_RIGHT;
case UCharacter.JoiningType.DUAL_JOINING:
return VALUE_DUAL;
case UCharacter.JoiningType.TRANSPARENT:
return VALUE_TRANSPARENT;
case UCharacter.JoiningType.NON_JOINING:
default:
return VALUE_NOSHAPE_NONE;
}
}
/*
* Chars in logical order.
* leftType is shaping code of char to logical left of range
* rightType is shaping code of char to logical right of range
*/
public static void shape(char[] chars, int leftType, int rightType, ClassTable isolClassTable) {
// iterate in logical order from left to right
//
// the effective right char is the most recently encountered
// non-transparent char
//
// four boolean states:
// the effective right char shapes
// the effective right char causes right shaping
// the current char shapes
// the current char causes left shaping
//
// if both cause shaping, then
// right += 2 (isolate to initial, or final to medial)
// cur += 1 (isolate to final)
// ern is effective right logical index
int ern = -1;
boolean rightShapes = false;
boolean rightCauses = (rightType & MASK_SHAPE_LEFT) != 0;
for (int n = 0; n < chars.length; n++) {
char c = chars[n];
int t = getShapeType(c);
if ((t & MASK_TRANSPARENT) != 0) {
continue;
}
boolean curShapes = (t & MASK_NOSHAPE) == 0;
boolean curCauses = (t & MASK_SHAPE_RIGHT) != 0;
if (rightCauses && curCauses) {
if (rightShapes) {
chars[ern] += 2;
}
if (curShapes) {
chars[n] = (char) (isolClassTable.getGlyphClassID(c) + 1);
}
} else {
if (curShapes) {
chars[n] = (char) isolClassTable.getGlyphClassID(c);
}
}
rightShapes = curShapes;
rightCauses = (t & MASK_SHAPE_LEFT) != 0;
ern = n;
}
if (rightShapes && rightCauses && (leftType & MASK_SHAPE_RIGHT) != 0) {
chars[ern] += 2;
}
}
}

View file

@ -0,0 +1,120 @@
/*
*******************************************************************************
* Copyright (C) 1998-2003, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
* Created on Dec 3, 2003
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/tool/layout/Attic/CharacterData.java,v $
* $Date: 2003/12/09 01:18:11 $
* $Revision: 1.1 $
*
*******************************************************************************
*/
package com.ibm.icu.dev.tool.layout;
import com.ibm.icu.lang.UCharacter;
import com.ibm.icu.lang.UProperty;
import com.ibm.icu.text.Normalizer;
import com.ibm.icu.text.UnicodeSet;
import com.ibm.icu.text.UnicodeSetIterator;
import com.ibm.icu.text.UTF16;
public class CharacterData
{
public class Record
{
public int getCodePoint()
{
return codePoint;
}
public int getGeneralCategory()
{
return generalCategory;
}
public int getDecompositionType()
{
return decompositionType;
}
public String getDecomposition()
{
return decomposition;
}
private Record(int character)
{
codePoint = character;
generalCategory = UCharacter.getType(character);
decompositionType = UCharacter.getIntPropertyValue(character, UProperty.DECOMPOSITION_TYPE);
switch (decompositionType) {
case UCharacter.DecompositionType.FINAL:
case UCharacter.DecompositionType.INITIAL:
case UCharacter.DecompositionType.ISOLATED:
case UCharacter.DecompositionType.MEDIAL:
decomposition = Normalizer.compose(UTF16.toString(character), true);
break;
case UCharacter.DecompositionType.CANONICAL:
decomposition = Normalizer.decompose(UTF16.toString(character), true);
break;
default:
decomposition = null;
}
}
private int codePoint;
private int generalCategory;
private int decompositionType;
private String decomposition;
}
private CharacterData(int charCount)
{
records = new Record[charCount];
}
private void add(int character)
{
records[recordIndex++] = new Record(character);
}
public Record getRecord(int index)
{
if (index < 0 || index >= records.length) {
return null;
}
return records[index];
}
public int countRecords()
{
return records.length;
}
// TODO: do we need to change this to use UnicodeSetIterator?
// That will mean not knowing the number of characters until
// after the iteration is done, so we'd have to use a vector
// to hold the Records at first and copy it to an array
// when we're done...
public static CharacterData factory(UnicodeSet characterSet)
{
int charCount = characterSet.size();
CharacterData data = new CharacterData(charCount);
for (int i = 0; i < charCount; i += 1) {
data.add(characterSet.charAt(i));
}
return data;
}
private Record[] records;
private int recordIndex = 0;
}

View file

@ -0,0 +1,247 @@
/*
*******************************************************************************
* Copyright (C) 1998-2003, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
* Created on Dec 3, 2003
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/tool/layout/ClassTable.java,v $
* $Date: 2003/12/09 01:18:11 $
* $Revision: 1.1 $
*
*******************************************************************************
*/
package com.ibm.icu.dev.tool.layout;
import java.io.*;
import java.util.*;
import java.lang.*;
import com.ibm.icu.impl.Utility;
public class ClassTable implements LookupSubtable
{
static class ClassEntry
{
private int glyphID;
private int classID;
public ClassEntry(int glyphID, int classID)
{
this.glyphID = glyphID;
this.classID = classID;
}
public int getGlyphID()
{
return glyphID;
}
public int getClassID()
{
return classID;
}
public int compareTo(ClassEntry that)
{
return this.glyphID - that.glyphID;
}
//
// Straight insertion sort from Knuth vol. III, pg. 81
//
public static void sort(ClassEntry[] table)
{
for (int j = 1; j < table.length; j += 1) {
int i;
ClassEntry v = table[j];
for (i = j - 1; i >= 0; i -= 1) {
if (v.compareTo(table[i]) >= 0) {
break;
}
table[i + 1] = table[i];
}
table[i + 1] = v;
}
}
public static int search(ClassEntry[] table, int glyphID)
{
int log2 = Utility.highBit(table.length);
int power = 1 << log2;
int extra = table.length - power;
int probe = power;
int index = 0;
if (table[extra].glyphID <= glyphID) {
index = extra;
}
while (probe > (1 << 0)) {
probe >>= 1;
if (table[index + probe].glyphID <= glyphID) {
index += probe;
}
}
if (table[index].glyphID == glyphID) {
return index;
}
return -1;
}
}
static class ClassRangeRecord
{
private int startGlyphID;
private int endGlyphID;
private int classID;
public ClassRangeRecord(int startGlyphID, int endGlyphID, int classID)
{
this.startGlyphID = startGlyphID;
this.endGlyphID = endGlyphID;
this.classID = classID;
}
public void write(OpenTypeTableWriter writer)
{
System.out.print(Utility.hex(startGlyphID, 6));
System.out.print(" - ");
System.out.print(Utility.hex(endGlyphID, 6));
System.out.print(": ");
System.out.println(classID);
writer.writeData(startGlyphID);
writer.writeData(endGlyphID);
writer.writeData(classID);
}
}
private Vector classMap;
private ClassEntry[] classTable;
private int snapshotSize;
public ClassTable()
{
this.classMap = new Vector();
this.classTable = null;
this.snapshotSize = -1;
}
public void addMapping(int charID, int classID)
{
ClassEntry entry = new ClassEntry(charID, classID);
classMap.addElement(entry);
}
public void addMapping(int startCharID, int endCharID, int classID)
{
for (int charID = startCharID; charID <= endCharID; charID += 1) {
addMapping(charID, classID);
}
}
public int getGlyphClassID(int glyphID)
{
int index = ClassEntry.search(classTable, glyphID);
if (index >= 0) {
return classTable[index].getClassID();
}
return 0;
}
public void snapshot()
{
if (snapshotSize != classMap.size()) {
snapshotSize = classMap.size();
classTable = new ClassEntry[snapshotSize];
for (int i = 0; i < snapshotSize; i += 1) {
classTable[i] = (ClassEntry) classMap.elementAt(i);
}
ClassEntry.sort(classTable);
}
}
public void writeClassTable(OpenTypeTableWriter writer)
{
snapshot();
Vector classRanges = new Vector();
int startIndex = 0;
while (startIndex < classTable.length) {
int startID = classTable[startIndex].getGlyphID();
int classID = classTable[startIndex].getClassID();
int nextID = startID;
int endID = startID;
int endIndex;
for (endIndex = startIndex; endIndex < classTable.length; endIndex += 1) {
if (classTable[endIndex].getGlyphID() != nextID ||
classTable[endIndex].getClassID() != classID) {
break;
}
endID = nextID;
nextID += 1;
}
if (classID != 0) {
ClassRangeRecord range = new ClassRangeRecord(startID, endID, classID);
classRanges.addElement(range);
}
startIndex = endIndex;
}
writer.writeData(2); // table format = 2 (class ranges)
writer.writeData(classRanges.size()); // class range count
for (int i = 0; i < classRanges.size(); i += 1) {
ClassRangeRecord range = (ClassRangeRecord) classRanges.elementAt(i);
range.write(writer);
}
}
public void writeLookupSubtable(OpenTypeTableWriter writer)
{
int singleSubstitutionsBase = writer.getOutputIndex();
int coverageTableIndex;
snapshot();
writer.writeData(2); // format 2: Specified output glyph indices
coverageTableIndex = writer.getOutputIndex();
writer.writeData(0); // offset to coverage table (fixed later)
writer.writeData(classTable.length); // number of glyphIDs in substitution array
for (int i = 0; i < classTable.length; i += 1) {
writer.writeData(classTable[i].getClassID());
}
writer.fixOffset(coverageTableIndex, singleSubstitutionsBase);
writer.writeData(1);
writer.writeData(classTable.length);
for (int i = 0; i < classTable.length; i += 1) {
writer.writeData(classTable[i].getGlyphID());
}
}
}

View file

@ -0,0 +1,142 @@
/*
*******************************************************************************
* Copyright (C) 1998-2003, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
* Created on Dec 3, 2003
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/tool/layout/FeatureList.java,v $
* $Date: 2003/12/09 01:18:11 $
* $Revision: 1.1 $
*
*******************************************************************************
*/
package com.ibm.icu.dev.tool.layout;
import java.io.*;
import java.lang.*;
import java.util.*;
public class FeatureList
{
static class FeatureRecord extends TaggedRecord
{
private int[] lookupIndices;
private int lookupCount;
public FeatureRecord(String theFeatureTag)
{
super(theFeatureTag);
lookupIndices = new int[10];
lookupCount = 0;
}
public void addLookup(int theLookupIndex)
{
if (lookupCount > lookupIndices.length) {
int[] newLookupIndices = new int[lookupIndices.length + 5];
System.arraycopy(lookupIndices, 0, newLookupIndices, 0, lookupIndices.length);
lookupIndices = newLookupIndices;
}
lookupIndices[lookupCount] = theLookupIndex;
lookupCount += 1;
}
public void writeFeatureRecord(OpenTypeTableWriter writer)
{
writer.writeData(0); // featureParams (must be NULL)
writer.writeData(lookupCount);
for (int i = 0; i < lookupCount; i += 1) {
writer.writeData(lookupIndices[i]);
}
}
}
private FeatureRecord[] featureRecords;
private int featureCount;
public FeatureList()
{
featureRecords = new FeatureRecord[10];
featureCount = 0;
}
private FeatureRecord findFeatureRecord(String featureTag)
{
for (int i = 0; i < featureCount; i += 1) {
FeatureRecord featureRecord = featureRecords[i];
if (featureRecord.getTag().equals(featureTag)) {
return featureRecord;
}
}
if (featureCount >= featureRecords.length) {
FeatureRecord[] newFeatureRecords = new FeatureRecord[featureCount + 5];
System.arraycopy(featureRecords, 0, newFeatureRecords, 0, featureRecords.length);
featureRecords = newFeatureRecords;
}
FeatureRecord newFeatureRecord = new FeatureRecord(featureTag);
featureRecords[featureCount] = newFeatureRecord;
featureCount += 1;
return newFeatureRecord;
}
public void addLookup(String featureTag, int lookupIndex)
{
FeatureRecord featureRecord = findFeatureRecord(featureTag);
featureRecord.addLookup(lookupIndex);
}
public void finalizeFeatureList()
{
TaggedRecord.sort(featureRecords, featureCount);
}
public int getFeatureIndex(String featureTag)
{
return TaggedRecord.search(featureRecords, featureCount, featureTag);
}
public void writeFeaturetList(OpenTypeTableWriter writer)
{
System.out.print("writing feature list...");
int featureListBase = writer.getOutputIndex();
writer.writeData(featureCount);
int featureRecordOffset = writer.getOutputIndex();
for (int i = 0; i < featureCount; i += 1) {
String tag = featureRecords[i].getTag();
System.out.print(" '" + tag + "'");
writer.writeTag(tag);
writer.writeData(0);
}
for (int i = 0; i < featureCount; i += 1) {
// fix the offset in the featureRecordArray.
// The "+2" skips over the tag and the "+3"
// skips to the next featureRecord entry
writer.fixOffset(featureRecordOffset + 2, featureListBase);
featureRecordOffset += 3;
featureRecords[i].writeFeatureRecord(writer);
}
System.out.println();
}
}

View file

@ -0,0 +1,58 @@
/*
*******************************************************************************
* Copyright (C) 1998-2003, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
* Created on Dec 3, 2003
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/tool/layout/GDEFWriter.java,v $
* $Date: 2003/12/09 01:18:11 $
* $Revision: 1.1 $
*
*******************************************************************************
*/
package com.ibm.icu.dev.tool.layout;
import java.io.*;
import java.util.*;
import java.lang.*;
class GDEFWriter extends OpenTypeTableWriter
{
ClassTable classTable;
String scriptName;
public GDEFWriter(String scriptName, ClassTable classTable)
{
super(1024);
this.classTable = classTable;
this.scriptName = scriptName;
}
public void writeTable(PrintStream output)
{
System.out.println("Writing " + scriptName + " GDEF table...");
// 0x0001000 (fixed1) version number
writeData(0x0001);
writeData(0x0000);
int classDefOffset = getOutputIndex();
writeData(0); // glyphClassDefOffset (will fix later);
writeData(0); // attachListOffset
writeData(0); // ligCaretListOffset
writeData(0); // markAttachClassDefOffset
fixOffset(classDefOffset, 0);
classTable.writeClassTable(this);
output.print("const le_uint8 ");
output.print(scriptName);
output.println("Shaping::glyphDefinitionTable[] = {");
dumpTable(output, 8);
output.println("};\n");
}
}

View file

@ -0,0 +1,69 @@
/*
*******************************************************************************
* Copyright (C) 1998-2003, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
* Created on Dec 3, 2003
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/tool/layout/GSUBWriter.java,v $
* $Date: 2003/12/09 01:18:11 $
* $Revision: 1.1 $
*
*******************************************************************************
*/
package com.ibm.icu.dev.tool.layout;
import java.io.*;
import java.util.*;
import java.lang.*;
public class GSUBWriter extends OpenTypeTableWriter
{
private ScriptList scriptList;
private FeatureList featureList;
private LookupList lookupList;
private String scriptName;
public GSUBWriter(String theScriptName, ScriptList theScriptList, FeatureList theFeatureList,
LookupList theLookupList)
{
super(1024);
scriptList = theScriptList;
featureList = theFeatureList;
lookupList = theLookupList;
scriptName = theScriptName;
}
public void writeTable(PrintStream output)
{
System.out.println("writing " + scriptName + " GSUB table...");
// 0x00010000 (fixed1) version number
writeData(0x0001);
writeData(0x0000);
int listOffset = getOutputIndex();
writeData(0); // script list offset (fixed later)
writeData(0); // feature list offset (fixed later)
writeData(0); // lookup list offset (fixed later)
fixOffset(listOffset++, 0);
scriptList.writeScriptList(this);
fixOffset(listOffset++, 0);
featureList.writeFeaturetList(this);
fixOffset(listOffset++, 0);
lookupList.writeLookupList(this);
output.print("const le_uint8 ");
output.print(scriptName);
output.println("Shaping::glyphSubstitutionTable[] = {");
dumpTable(output, 8);
output.println("};\n");
}
}

View file

@ -6,7 +6,7 @@
*
* Created on Apr 4, 2003
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/tool/layout/LanguageData.java,v $ $Date: 2003/04/15 20:15:53 $ $Revision: 1.2 $
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/tool/layout/LanguageData.java,v $ $Date: 2003/12/09 01:18:12 $ $Revision: 1.3 $
*
*******************************************************************************
*/
@ -18,7 +18,7 @@ package com.ibm.icu.dev.tool.layout;
* @author emader
*
*/
public class LanguageData
public class LanguageData extends TagValueData
{
public static class Record
{
@ -93,48 +93,48 @@ public class LanguageData
private int minLanguage = 0;
private int maxLanguage = minLanguage + languages.length - 1;
public int getMinLanguage()
public int getMinValue()
{
return minLanguage;
}
public int getMaxLanguage()
public int getMaxValue()
{
return maxLanguage;
}
public String getLanguageTag(int language)
public String getTag(int value)
{
if (language < minLanguage || language > maxLanguage) {
if (value < minLanguage || value > maxLanguage) {
return null;
}
return languages[language - minLanguage].tag();
return languages[value - minLanguage].tag();
}
public String getLanguageTagLabel(int language)
public String getTagLabel(int value)
{
if (language < minLanguage || language > maxLanguage) {
if (value < minLanguage || value > maxLanguage) {
return null;
}
return languages[language - minLanguage].label();
return languages[value - minLanguage].label();
}
public String makeLanguageTag(int language)
public String makeTag(int value)
{
if (language < minLanguage || language > maxLanguage) {
if (value < minLanguage || value > maxLanguage) {
return null;
}
return languages[language - minLanguage].makeTag();
return languages[value - minLanguage].makeTag();
}
public String getLanguageName(int language) {
if (language < minLanguage || language > maxLanguage) {
public String getName(int value) {
if (value < minLanguage || value > maxLanguage) {
return "(UNKNOWN)";
}
return languages[language - minLanguage].name();
return languages[value - minLanguage].name();
}
}

View file

@ -0,0 +1,46 @@
/*
*******************************************************************************
* Copyright (C) 1998-2003, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
* Created on Dec 3, 2003
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/tool/layout/LigatureEntry.java,v $
* $Date: 2003/12/09 01:18:11 $
* $Revision: 1.1 $
*
*******************************************************************************
*/
package com.ibm.icu.dev.tool.layout;
import java.util.*;
import java.lang.*;
public class LigatureEntry
{
private int[] componentChars;
private int ligature;
public LigatureEntry(int ligature, int[] componentChars, int componentCount)
{
this.componentChars = new int[componentCount];
this.ligature = ligature;
System.arraycopy(componentChars, 0, this.componentChars, 0, componentCount);
}
public int getComponentCount()
{
return componentChars.length;
}
public int getComponentChar(int componentIndex)
{
return componentChars[componentIndex];
}
public int getLigature()
{
return ligature;
}
}

View file

@ -0,0 +1,33 @@
/*
*******************************************************************************
* Copyright (C) 1998-2003, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
* Created on Dec 3, 2003
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/tool/layout/LigatureModuleWriter.java,v $
* $Date: 2003/12/09 01:18:11 $
* $Revision: 1.1 $
*
*******************************************************************************
*/
package com.ibm.icu.dev.tool.layout;
import java.io.PrintStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;
public class LigatureModuleWriter extends ModuleWriter
{
public LigatureModuleWriter()
{
super();
}
public void writeTable(OpenTypeTableWriter tableWriter)
{
tableWriter.writeTable(output);
}
}

View file

@ -0,0 +1,230 @@
/*
*******************************************************************************
* Copyright (C) 1998-2003, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
* Created on Dec 3, 2003
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/tool/layout/LigatureTree.java,v $
* $Date: 2003/12/09 01:18:11 $
* $Revision: 1.1 $
*
*******************************************************************************
*/
package com.ibm.icu.dev.tool.layout;
import java.io.*;
import java.lang.*;
import java.util.*;
import com.ibm.icu.text.UTF16;
import com.ibm.icu.impl.Utility;
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;
}
void insert(int[] chars, int index)
{
int c = chars[index];
int len = chars.length;
if (len == index + 1) {
if (ligature != -1) {
System.out.println("overwriting ligature " + Utility.hex(ligature, 6) + " with " + Utility.hex(c, 6));
}
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();
}
}

View file

@ -0,0 +1,150 @@
/*
*******************************************************************************
* Copyright (C) 1998-2003, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
* Created on Dec 3, 2003
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/tool/layout/LigatureTreeWalker.java,v $
* $Date: 2003/12/09 01:18:11 $
* $Revision: 1.1 $
*
*******************************************************************************
*/
package com.ibm.icu.dev.tool.layout;
import java.io.*;
import java.util.*;
import java.lang.*;
import com.ibm.icu.impl.Utility;
public class LigatureTreeWalker extends TreeWalker implements LookupSubtable
{
protected int[] componentChars;
protected int componentCount;
protected int lastFirstComponent;
protected Vector ligatureSets;
protected Vector ligatureSet;
public LigatureTreeWalker()
{
componentChars = new int[30];
componentCount = 0;
lastFirstComponent = -1;
ligatureSet = null;
ligatureSets = new Vector();
}
public void down(int ch)
{
componentChars[componentCount] = ch;
componentCount += 1;
}
public void up()
{
if (componentCount > 0) {
componentCount -= 1;
}
}
public void ligature(int lig)
{
int firstComponent = componentChars[0];
if (lastFirstComponent != firstComponent) {
if (ligatureSet != null) {
ligatureSets.addElement(ligatureSet);
}
ligatureSet = new Vector();
lastFirstComponent = firstComponent;
}
ligatureSet.addElement(new LigatureEntry(lig, componentChars, componentCount));
}
public void done()
{
if (ligatureSet != null) {
ligatureSets.addElement(ligatureSet);
}
}
protected int firstComponentChar(int ligatureSetIndex)
{
Vector ligatureSet = (Vector) ligatureSets.elementAt(ligatureSetIndex);
LigatureEntry firstEntry = (LigatureEntry) ligatureSet.elementAt(0);
return firstEntry.getComponentChar(0);
}
protected void writeCoverageTable(OpenTypeTableWriter writer)
{
int ligatureSetCount = ligatureSets.size();
writer.writeData(1);
writer.writeData(ligatureSetCount);
for (int set = 0; set < ligatureSetCount; set += 1) {
writer.writeData(firstComponentChar(set));
}
}
public void writeLookupSubtable(OpenTypeTableWriter writer)
{
int coverageOffset, ligatureSetOffset, ligatureTableOffset;
int ligatureSubstitutionBase = writer.getOutputIndex();
int ligatureSetCount = ligatureSets.size();
//System.out.println("Writing " + tableName + "...");
writer.writeData(1); // substFormat
coverageOffset = writer.getOutputIndex();
writer.writeData(0); // coverageTableOffset (will fix later)
writer.writeData(ligatureSetCount);
ligatureSetOffset = writer.getOutputIndex();
for (int set = 0; set < ligatureSetCount; set += 1) {
writer.writeData(0); // ligatureSet offset - will fix later
}
for (int set = 0; set < ligatureSetCount; set += 1) {
System.out.print(Utility.hex(firstComponentChar(set), 6) + ": ");
Vector ligatureSet = (Vector) ligatureSets.elementAt(set);
int ligatureCount = ligatureSet.size();
int ligatureSetAddress = writer.getOutputIndex();
System.out.println(ligatureCount + " ligatures.");
writer.fixOffset(ligatureSetOffset++, ligatureSubstitutionBase);
writer.writeData(ligatureCount);
ligatureTableOffset = writer.getOutputIndex();
for (int lig = 0; lig < ligatureCount; lig += 1) {
writer.writeData(0); // ligatureTableOffset (will fix later)
}
for (int lig = 0; lig < ligatureCount; lig += 1) {
LigatureEntry entry = (LigatureEntry) ligatureSet.elementAt(lig);
int componentCount = entry.getComponentCount();
writer.fixOffset(ligatureTableOffset++, ligatureSetAddress);
writer.writeData(entry.getLigature());
writer.writeData(componentCount);
for (int comp = 1; comp < componentCount; comp += 1) {
writer.writeData(entry.getComponentChar(comp));
}
}
}
writer.fixOffset(coverageOffset, ligatureSubstitutionBase);
writeCoverageTable(writer);
}
}

View file

@ -0,0 +1,96 @@
/*
*******************************************************************************
* Copyright (C) 1998-2003, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
* Created on Dec 3, 2003
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/tool/layout/Lookup.java,v $
* $Date: 2003/12/09 01:18:11 $
* $Revision: 1.1 $
*
*******************************************************************************
*/
package com.ibm.icu.dev.tool.layout;
import java.io.*;
import java.lang.*;
import java.util.*;
public /*abstract*/ class Lookup
{
private int lookupType;
private int lookupFlags;
private LookupSubtable[] subtables;
private int subtableCount;
// Lookup flags
public final static int LF_ReservedBit = 0x0001;
public final static int LF_IgnoreBaseGlyphs = 0x0002;
public final static int LF_IgnoreLigatures = 0x0004;
public final static int LF_IgnoreMarks = 0x0008;
public final static int LF_ReservedMask = 0x00F0;
public final static int LF_MarkAttachTypeMask = 0xFF00;
public final static int LF_MarkAttachTypeShift = 8;
// GSUB lookup types
public final static int GSST_Single = 1;
public final static int GSST_Multiple = 2;
public final static int GSST_Alternate = 3;
public final static int GSST_Ligature = 4;
public final static int GSST_Context = 5;
public final static int GSST_ChainingContext = 6;
// GPOS lookup types
public final static int GPST_Single = 1;
public final static int GPST_Pair = 2;
public final static int GPST_Cursive = 3;
public final static int GPST_MarkToBase = 4;
public final static int GPST_MarkToLigature = 5;
public final static int GPST_MarkToMark = 6;
public final static int GPST_Context = 7;
public final static int GPST_ChainingContext = 8;
public Lookup(int theLookupType, int theLookupFlags)
{
lookupType = theLookupType;
lookupFlags = theLookupFlags;
subtables = new LookupSubtable[10];
subtableCount = 0;
}
public void addSubtable(LookupSubtable subtable)
{
if (subtableCount >= subtables.length) {
LookupSubtable[] newSubtables = new LookupSubtable[subtables.length + 5];
System.arraycopy(subtables, 0, newSubtables, 0, subtables.length);
subtables = newSubtables;
}
subtables[subtableCount] = subtable;
subtableCount += 1;
}
public void writeLookup(OpenTypeTableWriter writer)
{
int lookupBase = writer.getOutputIndex();
writer.writeData(lookupType);
writer.writeData(lookupFlags);
writer.writeData(subtableCount);
int subtableOffset = writer.getOutputIndex();
for (int i = 0; i < subtableCount; i += 1) {
writer.writeData(0);
}
for (int i = 0; i < subtableCount; i += 1) {
writer.fixOffset(subtableOffset++, lookupBase);
subtables[i].writeLookupSubtable(writer);
}
}
}

View file

@ -0,0 +1,65 @@
/*
*******************************************************************************
* Copyright (C) 1998-2003, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
* Created on Dec 3, 2003
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/tool/layout/LookupList.java,v $
* $Date: 2003/12/09 01:18:12 $
* $Revision: 1.1 $
*
*******************************************************************************
*/
package com.ibm.icu.dev.tool.layout;
import java.io.*;
import java.util.*;
import java.lang.*;
public class LookupList
{
private Lookup[] lookups;
private int lookupCount;
public LookupList()
{
lookups = new Lookup[10];
lookupCount = 0;
}
public int addLookup(Lookup lookup)
{
if (lookupCount >= lookups.length) {
Lookup[] newLookups = new Lookup[lookups.length + 5];
System.arraycopy(lookups, 0, newLookups, 0, lookups.length);
lookups = newLookups;
}
lookups[lookupCount] = lookup;
return lookupCount++;
}
public void writeLookupList(OpenTypeTableWriter writer)
{
System.out.println("writing lookup list...");
int lookupListBase = writer.getOutputIndex();
writer.writeData(lookupCount);
int lookupOffset = writer.getOutputIndex();
for (int i = 0; i < lookupCount; i += 1) {
writer.writeData(0); // Offset to lookup (fixed later);
}
for (int i = 0; i < lookupCount; i += 1) {
writer.fixOffset(lookupOffset++, lookupListBase);
lookups[i].writeLookup(writer);
}
}
}

View file

@ -0,0 +1,24 @@
/*
*******************************************************************************
* Copyright (C) 1998-2003, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
* Created on Dec 3, 2003
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/tool/layout/LookupSubtable.java,v $
* $Date: 2003/12/09 01:18:11 $
* $Revision: 1.1 $
*
*******************************************************************************
*/
package com.ibm.icu.dev.tool.layout;
import java.io.*;
import java.lang.*;
import java.util.*;
public interface LookupSubtable
{
void writeLookupSubtable(OpenTypeTableWriter writer);
}

View file

@ -4,76 +4,104 @@
* others. All Rights Reserved. *
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/tool/layout/ModuleWriter.java,v $
* $Date: 2003/06/03 18:49:31 $
* $Revision: 1.4 $
* Created on Dec 3, 2003
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/tool/layout/ModuleWriter.java,v $
* $Date: 2003/12/09 01:18:11 $
* $Revision: 1.5 $
*
*******************************************************************************
*/
package com.ibm.icu.dev.tool.layout;
import java.io.PrintStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;
public class ModuleWriter
{
public ModuleWriter(ScriptData theScriptData, LanguageData theLanguageData)
public ModuleWriter()
{
scriptData = theScriptData;
languageData = theLanguageData;
wroteDefine = false;
output = null;
}
public void openFile(String outputFileName)
{
public void openFile(String outputFileName) {
try
{
output = new PrintStream(
new FileOutputStream(outputFileName));
}
catch (IOException e)
{
} catch (IOException e) {
System.out.println("? Could not open " + outputFileName + " for writing.");
return;
}
System.out.println("\nWriting module " + outputFileName + "...");
}
public void writeHeader()
{
output.print(moduleHeader);
}
public void includeFile(String fileName)
{
output.print("#include \"");
output.print(fileName);
output.println("\"");
};
wroteDefine = false;
System.out.println("Writing module " + outputFileName + "...");
}
public void closeFile()
{
public void writeHeader(String define, String[] includeFiles) {
output.print(moduleHeader);
if (define != null) {
wroteDefine = true;
output.print("#ifndef ");
output.println(define);
output.print("#define ");
output.println(define);
output.println();
}
if (includeFiles != null) {
for (int i = 0; i < includeFiles.length; i += 1) {
output.print("#include \"");
output.print(includeFiles[i]);
output.println("\"");
}
output.println();
}
output.print(moduleBegin);
}
public void writeTrailer() {
output.print(moduleTrailer);
if (wroteDefine) {
output.println("#endif");
}
}
public void closeFile() {
System.out.println("Done.");
output.close();
}
protected ScriptData scriptData;
protected LanguageData languageData;
protected PrintStream output;
protected boolean wroteDefine;
protected static final String moduleHeader =
"/*\n" +
" *\n" +
" * (C) Copyright IBM Corp. 1998 - 2003. All Rights Reserved.\n" +
" *\n" +
" * WARNING: THIS FILE IS MACHINE GENERATED. DO NOT HAND EDIT IT UNLESS\n" +
" * YOU REALLY KNOW WHAT YOU'RE DOING.\n" +
" *\n" +
" * $Source" + "$\n" +
" * $Date" + "$\n" +
" * $Revision" + "$\n" +
" */\n" +
"\n";
}
protected PrintStream output;
protected static final String moduleHeader = "/*\n" +
" *\n" +
" * (C) Copyright IBM Corp. 1998-2003. All Rights Reserved.\n" +
" *\n" +
" * WARNING: THIS FILE IS MACHINE GENERATED. DO NOT HAND EDIT IT UNLESS\n" +
" * YOU REALLY KNOW WHAT YOU'RE DOING.\n" +
" *\n" +
" * $Source" + "$\n" +
" * $Date" + "$\n" +
" * $Revision" + "$\n" +
" */\n" +
"\n";
protected static final String moduleBegin = "U_NAMESPACE_BEGIN\n\n";
protected static final String moduleTrailer = "U_NAMESPACE_END\n";
}

View file

@ -0,0 +1,132 @@
/*
*******************************************************************************
* Copyright (C) 1998-2003, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
* Created on Dec 3, 2003
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/tool/layout/OpenTypeTableWriter.java,v $
* $Date: 2003/12/09 01:18:11 $
* $Revision: 1.1 $
*
*******************************************************************************
*/
package com.ibm.icu.dev.tool.layout;
import java.io.*;
import java.util.*;
import com.ibm.icu.impl.Utility;
abstract class OpenTypeTableWriter
{
static class OpenTypeTableDumper
{
private short[] table;
private int tableLength;
OpenTypeTableDumper(short[] data, int outputIndex)
{
table = data;
tableLength = outputIndex;
}
int length()
{
return tableLength;
}
void appendValue(StringBuffer line, int index)
{
short value = table[index];
line.append("0x");
line.append(Utility.hex((value >> 8) & 0xFF, 2));
line.append(", ");
line.append("0x");
line.append(Utility.hex(value & 0xFF, 2));
}
void dumpTable(PrintStream output, int valuesPerLine) {
StringBuffer line = new StringBuffer(" "); // four spaces
int maxIndex = length();
for (int i = 0; i < maxIndex; i += 1) {
if (i > 0 && i % valuesPerLine == 0) {
output.println(line.toString());
line.setLength(4);
}
appendValue(line, i);
line.append(", ");
}
line.setLength(line.length() - 2);
output.println(line.toString());
}
}
protected short[] data;
protected int outputIndex;
public OpenTypeTableWriter(int initialBufferSize)
{
data = new short[initialBufferSize];
outputIndex = 0;
}
public OpenTypeTableWriter()
{
this(1024);
}
public int getOutputIndex()
{
return outputIndex;
}
public void writeData(int value)
{
if (outputIndex >= data.length)
{
short[] newData = new short[data.length + 512];
System.arraycopy(data, 0, newData, 0, data.length);
data = newData;
}
data[outputIndex] = (short) value;
outputIndex += 1;
}
public void writeTag(String tag)
{
char[] charArray = {'\0', '\0', '\0', '\0'};
int max = Math.min(tag.length(), 4);
tag.getChars(0, max, charArray, 0);
writeData(((charArray[0] & 0xFF) << 8) + (charArray[1] & 0xFF));
writeData(((charArray[2] & 0xFF) << 8) + (charArray[3] & 0xFF));
}
public void fixOffset(int offset, int base)
{
// * 2 to convert from short to byte index
data[offset] = (short) ((outputIndex - base) * 2);
}
public void dumpTable(PrintStream output, int valuesPerLine)
{
OpenTypeTableDumper dumper = new OpenTypeTableDumper(data, outputIndex);
dumper.dumpTable(output, valuesPerLine);
}
abstract public void writeTable(PrintStream output);
}

View file

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/tool/layout/ScriptData.java,v $
* $Date: 2003/06/03 18:49:31 $
* $Revision: 1.3 $
* $Date: 2003/12/09 01:18:11 $
* $Revision: 1.4 $
*
*******************************************************************************
*/
@ -21,7 +21,7 @@ import com.ibm.icu.text.UnicodeSet;
import com.ibm.icu.text.UnicodeSetIterator;
import com.ibm.icu.impl.Utility;
public class ScriptData
public class ScriptData extends TagValueData
{
public static class Record
{
@ -138,12 +138,12 @@ public class ScriptData
System.out.println("Done.");
}
public int getMinScript()
public int getMinValue()
{
return fMinScript;
}
public int getMaxScript()
public int getMaxValue()
{
return fMaxScript;
}
@ -153,33 +153,33 @@ public class ScriptData
return fRecords.length;
}
public String getScriptTag(int scriptCode)
public String getTag(int value)
{
if (scriptCode >= fMinScript && scriptCode <= fMaxScript) {
return fScriptTags[scriptCode - fMinScript];
if (value >= fMinScript && value <= fMaxScript) {
return fScriptTags[value - fMinScript];
}
return "zyyx";
}
public String getScriptTagLabel(int scriptCode)
public String getTagLabel(int value)
{
return getScriptTag(scriptCode);
return getTag(value);
}
public String makeScriptTag(int scriptCode)
public String makeTag(int value)
{
if (scriptCode >= fMinScript && scriptCode <= fMaxScript) {
return TagUtilities.makeTag(fScriptTags[scriptCode - fMinScript]);
if (value >= fMinScript && value <= fMaxScript) {
return TagUtilities.makeTag(fScriptTags[value - fMinScript]);
} else {
return "0x00000000";
}
}
public String getScriptName(int scriptCode)
public String getName(int value)
{
if (scriptCode >= fMinScript && scriptCode <= fMaxScript) {
return fScriptNames[scriptCode - fMinScript];
if (value >= fMinScript && value <= fMaxScript) {
return fScriptNames[value - fMinScript];
}
return "COMMON";

View file

@ -0,0 +1,109 @@
/*
*******************************************************************************
* Copyright (C) 1998-2003, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/tool/layout/ScriptIDModuleWriter.java,v $
* $Date: 2003/12/09 01:18:11 $
* $Revision: 1.1 $
*
*******************************************************************************
*/
package com.ibm.icu.dev.tool.layout;
public class ScriptIDModuleWriter extends ScriptModuleWriter
{
public ScriptIDModuleWriter(ScriptData scriptData, LanguageData languageData)
{
super(scriptData, languageData);
}
public void writeScriptHeader(String fileName)
{
int minScript = scriptData.getMinValue();
int maxScript = scriptData.getMaxValue();
openFile(fileName);
writeHeader("__LESCRIPTS_H", null);
output.println(scriptPreamble);
for (int script = minScript; script <= maxScript; script += 1) {
output.print(" ");
output.print(scriptData.getTag(script));
output.print("ScriptCode = ");
if (script < 10) {
output.print(" ");
}
output.print(script);
output.println(",");
}
output.println();
output.print(" scriptCodeCount = ");
output.println(maxScript - minScript + 1);
output.println(postamble);
writeTrailer();
closeFile();
}
public void writeLanguageHeader(String fileName)
{
int minLanguage = languageData.getMinValue();
int maxLanguage = languageData.getMaxValue();
openFile(fileName);
writeHeader("__LELANGUAGES_H", null);
output.println(languagePreamble);
for (int language = minLanguage; language <= maxLanguage; language += 1) {
output.print(" ");
output.print(languageData.getTagLabel(language).toLowerCase());
output.print("LanguageCode = ");
if (language < 10) {
output.print(" ");
}
output.print(language);
output.println(",");
}
output.println();
output.print(" languageCodeCount = ");
output.println(maxLanguage - minLanguage + 1);
output.println(postamble);
writeTrailer();
closeFile();
}
private static final String scriptPreamble =
"/**\n" +
" * Constants for Unicode script values, generated using\n" +
" * ICU4J's <code>UScript</code> class.\n" +
" *\n" +
" * @draft ICU 2.6\n" +
" */\n" +
"\n" +
"enum ScriptCodes {";
private static final String languagePreamble =
"/**\n" +
" * A provisional list of language codes. For now,\n" +
" * this is just a list of languages which the LayoutEngine\n" +
" * supports.\n" +
" *\n" +
" * @draft ICU 2.6\n" +
" */\n" +
"\n" +
"enum LanguageCodes {";
private static final String postamble =
"};\n";
}

View file

@ -0,0 +1,208 @@
/*
*******************************************************************************
* Copyright (C) 1998-2003, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
* Created on Dec 3, 2003
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/tool/layout/ScriptList.java,v $
* $Date: 2003/12/09 01:18:12 $
* $Revision: 1.1 $
*
*******************************************************************************
*/
package com.ibm.icu.dev.tool.layout;
import java.io.*;
import java.lang.*;
import java.util.*;
public class ScriptList
{
static class LangSysRecord extends TaggedRecord
{
private int[] featureIndices;
private int featureCount;
public LangSysRecord(String theLanguageTag)
{
super(theLanguageTag);
featureIndices = new int[10];
featureCount = 0;
}
public void addFeature(int theFeatureIndex)
{
if (featureCount > featureIndices.length) {
int[] newFeatureIndices = new int[featureIndices.length + 5];
System.arraycopy(featureIndices, 0, newFeatureIndices, 0, featureIndices.length);
featureIndices = newFeatureIndices;
}
featureIndices[featureCount] = theFeatureIndex;
featureCount += 1;
}
public void writeLangSysRecord(OpenTypeTableWriter writer)
{
writer.writeData(0); // lookupOrder (must be NULL)
writer.writeData(0xFFFF); // reqFeatureIndex (0xFFFF means none)
writer.writeData(featureCount);
for (int i = 0; i < featureCount; i += 1) {
writer.writeData(featureIndices[i]);
}
}
}
static class ScriptRecord extends TaggedRecord
{
private LangSysRecord[] langSysRecords;
private int langSysCount;
public ScriptRecord(String theScriptTag)
{
super(theScriptTag);
langSysRecords = new LangSysRecord[10];
langSysCount = 0;
}
public LangSysRecord findLangSysRecord(String languageTag)
{
for (int i = 0; i < langSysCount; i += 1) {
LangSysRecord langSysRecord = langSysRecords[i];
if (langSysRecord.getTag().equals(languageTag)) {
return langSysRecord;
}
}
if (langSysCount >= langSysRecords.length) {
LangSysRecord[] newLangSysRecords = new LangSysRecord[langSysCount + 5];
System.arraycopy(langSysRecords, 0, newLangSysRecords, 0, langSysRecords.length);
langSysRecords = newLangSysRecords;
}
LangSysRecord newLangSysRecord = new LangSysRecord(languageTag);
langSysRecords[langSysCount] = newLangSysRecord;
langSysCount += 1;
return newLangSysRecord;
}
public void writeScriptRecord(OpenTypeTableWriter writer)
{
TaggedRecord.sort(langSysRecords, langSysCount);
int scriptTableBase = writer.getOutputIndex();
int firstLangSys = 0;
writer.writeData(0); // default langSys offset (fixed later)
if (langSysRecords[0].getTag().equals("(default)")) {
firstLangSys = 1;
}
writer.writeData(langSysCount - firstLangSys);
int langSysOffset = writer.getOutputIndex();
for (int i = firstLangSys; i < langSysCount; i += 1) {
writer.writeTag(langSysRecords[i].getTag());
writer.writeData(0);
}
if (firstLangSys > 0) {
System.out.print(" (default)");
writer.fixOffset(scriptTableBase, scriptTableBase);
langSysRecords[0].writeLangSysRecord(writer);
}
for (int i = firstLangSys; i < langSysCount; i += 1) {
// fix the offset in the langSysRecordArray.
// The "+2" skips over the tag and the "+3"
// skips to the next langSysRecord entry
writer.fixOffset(langSysOffset + 2, scriptTableBase);
langSysOffset += 3;
System.out.print(" '" + langSysRecords[i].getTag() + "'");
langSysRecords[i].writeLangSysRecord(writer);
}
}
}
private ScriptRecord[] scriptRecords;
private int scriptCount;
public ScriptList()
{
scriptRecords = new ScriptRecord[10];
scriptCount = 0;
}
private LangSysRecord findLangSysRecord(String scriptTag, String languageTag)
{
for (int i = 0; i < scriptCount; i += 1) {
ScriptRecord scriptRecord = scriptRecords[i];
if (scriptRecord.getTag().equals(scriptTag)) {
return scriptRecord.findLangSysRecord(languageTag);
}
}
if (scriptCount >= scriptRecords.length) {
ScriptRecord[] newScriptRecords = new ScriptRecord[scriptCount + 5];
System.arraycopy(scriptRecords, 0, newScriptRecords, 0, scriptRecords.length);
scriptRecords = newScriptRecords;
}
ScriptRecord newScriptRecord = new ScriptRecord(scriptTag);
scriptRecords[scriptCount] = newScriptRecord;
scriptCount += 1;
return newScriptRecord.findLangSysRecord(languageTag);
}
public void addFeature(String scriptTag, String languageTag, int featureIndex)
{
LangSysRecord langSysRecord = findLangSysRecord(scriptTag, languageTag);
langSysRecord.addFeature(featureIndex);
}
public void writeScriptList(OpenTypeTableWriter writer)
{
System.out.println("writing script list...");
int scriptListBase = writer.getOutputIndex();
TaggedRecord.sort(scriptRecords, scriptCount);
writer.writeData(scriptCount);
int scriptRecordOffset = writer.getOutputIndex();
for (int i = 0; i < scriptCount; i += 1) {
writer.writeTag(scriptRecords[i].getTag());
writer.writeData(0);
}
for (int i = 0; i < scriptCount; i += 1) {
// fix the offset in the scriptRecordArray.
// The "+2" skips over the tag and the "+3"
// skips to the next scriptRecord entry
writer.fixOffset(scriptRecordOffset + 2, scriptListBase);
scriptRecordOffset += 3;
System.out.print(" script '" + scriptRecords[i].getTag() + "':");
scriptRecords[i].writeScriptRecord(writer);
System.out.println();
}
}
}

View file

@ -5,114 +5,27 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/tool/layout/ScriptModuleWriter.java,v $
* $Date: 2003/06/03 18:49:31 $
* $Revision: 1.3 $
* $Date: 2003/12/09 01:18:11 $
* $Revision: 1.4 $
*
*******************************************************************************
*/
package com.ibm.icu.dev.tool.layout;
import java.io.PrintStream;
import java.io.FileOutputStream;
import java.io.IOException;
public class ScriptModuleWriter extends ModuleWriter
{
public ScriptModuleWriter(ScriptData scriptData, LanguageData languageData)
public ScriptModuleWriter(ScriptData theScriptData, LanguageData theLanguageData)
{
super(scriptData, languageData);
super();
scriptData = theScriptData;
languageData = theLanguageData;
}
public void writeScriptHeader(String fileName)
{
int minScript = scriptData.getMinScript();
int maxScript = scriptData.getMaxScript();
openFile(fileName);
writeHeader();
output.println(scriptPreamble);
for (int script = minScript; script <= maxScript; script += 1) {
output.print(" ");
output.print(scriptData.getScriptTag(script));
output.print("ScriptCode = ");
if (script < 10) {
output.print(" ");
}
output.print(script);
output.println(",");
}
output.println();
output.print(" scriptCodeCount = ");
output.println(maxScript - minScript + 1);
output.println(postamble);
closeFile();
}
public void writeLanguageHeader(String fileName)
{
int minLanguage = languageData.getMinLanguage();
int maxLanguage = languageData.getMaxLanguage();
openFile(fileName);
writeHeader();
output.println(languagePreamble);
for (int language = minLanguage; language <= maxLanguage; language += 1) {
output.print(" ");
output.print(languageData.getLanguageTagLabel(language).toLowerCase());
output.print("LanguageCode = ");
if (language < 10) {
output.print(" ");
}
output.print(language);
output.println(",");
}
output.println();
output.print(" languageCodeCount = ");
output.println(maxLanguage - minLanguage + 1);
output.println(postamble);
closeFile();
}
private static final String scriptPreamble =
"#ifndef __LESCRIPTS_H\n" +
"#define __LESCRIPTS_H\n" +
"\n" +
"U_NAMESPACE_BEGIN\n" +
"\n" +
"/**\n" +
" * Constants for Unicode script values, generated using\n" +
" * ICU4J's <code>UScript</code> class.\n" +
" *\n" +
" * @draft ICU 2.6\n" +
" */\n" +
"\n" +
"enum ScriptCodes {";
private static final String languagePreamble =
"#ifndef __LELANGUAGES_H\n" +
"#define __LELANGUAGES_H\n" +
"\n" +
"U_NAMESPACE_BEGIN\n" +
"\n" +
"/**\n" +
" * A provisional list of language codes. For now,\n" +
" * this is just a list of languages which the LayoutEngine\n" +
" * supports.\n" +
" *\n" +
" * @draft ICU 2.6\n" +
" */\n" +
"\n" +
"enum LanguageCodes {";
private static final String postamble =
"};\n" +
"\n" +
"U_NAMESPACE_END\n" +
"#endif";
protected ScriptData scriptData;
protected LanguageData languageData;
}

View file

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/tool/layout/ScriptNameBuilder.java,v $
* $Date: 2003/06/03 18:49:32 $
* $Revision: 1.3 $
* $Date: 2003/12/09 01:18:12 $
* $Revision: 1.4 $
*
*******************************************************************************
*/
@ -25,10 +25,10 @@ public class ScriptNameBuilder
ScriptData scriptData = new ScriptData();
LanguageData languageData = new LanguageData();
ScriptModuleWriter scriptModuleWriter = new ScriptModuleWriter(scriptData, languageData);
ScriptIDModuleWriter scriptIDModuleWriter = new ScriptIDModuleWriter(scriptData, languageData);
scriptModuleWriter.writeScriptHeader("LEScripts.h");
scriptModuleWriter.writeLanguageHeader("LELanguages.h");
scriptIDModuleWriter.writeScriptHeader("LEScripts.h");
scriptIDModuleWriter.writeLanguageHeader("LELanguages.h");
ScriptTagModuleWriter scriptTagModuleWriter = new ScriptTagModuleWriter(scriptData, languageData);

View file

@ -5,8 +5,8 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/tool/layout/ScriptRunModuleWriter.java,v $
* $Date: 2003/06/03 18:49:32 $
* $Revision: 1.3 $
* $Date: 2003/12/09 01:18:11 $
* $Revision: 1.4 $
*
*******************************************************************************
*/
@ -15,7 +15,7 @@ package com.ibm.icu.dev.tool.layout;
import java.util.*;
import com.ibm.icu.impl.Utility;
public class ScriptRunModuleWriter extends ModuleWriter
public class ScriptRunModuleWriter extends ScriptModuleWriter
{
public ScriptRunModuleWriter(ScriptData theScriptData)
{
@ -24,12 +24,12 @@ public class ScriptRunModuleWriter extends ModuleWriter
public void writeScriptRuns(String fileName)
{
int minScript = scriptData.getMinScript();
int maxScript = scriptData.getMaxScript();
int minScript = scriptData.getMinValue();
int maxScript = scriptData.getMaxValue();
int recordCount = scriptData.getRecordCount();
openFile(fileName);
writeHeader();
writeHeader(null, includeFiles);
output.println(preamble);
for (int record = 0; record < recordCount; record += 1) {
@ -40,11 +40,11 @@ public class ScriptRunModuleWriter extends ModuleWriter
output.print(", 0x");
output.print(Utility.hex(scriptData.getRecord(record).endChar(), 6));
output.print(", ");
output.print(scriptData.getScriptTag(script));
output.print(scriptData.getTag(script));
output.print("ScriptCode}");
output.print((record == recordCount - 1) ? " " : ",");
output.print(" // ");
output.println(scriptData.getScriptName(script));
output.println(scriptData.getName(script));
}
output.println(postamble);
@ -77,9 +77,9 @@ public class ScriptRunModuleWriter extends ModuleWriter
Vector offsets = scriptRangeOffsets[script - minScript];
output.print("le_int16 ");
output.print(scriptData.getScriptTag(script));
output.print(scriptData.getTag(script));
output.println("ScriptRanges[] = {");
output.print(" ");
output.print(" ");
for (int offset = 0; offset < offsets.size(); offset += 1) {
Integer i = (Integer) offsets.elementAt(offset);
@ -89,29 +89,29 @@ public class ScriptRunModuleWriter extends ModuleWriter
}
output.println("-1");
output.println("};\n");
output.println(postamble);
}
output.println("le_int16 *ScriptRun::scriptRangeOffsets[] = {");
for (int script = minScript; script <= maxScript; script += 1) {
output.print(" ");
output.print(scriptData.getScriptTag(script));
output.print(scriptData.getTag(script));
output.print("ScriptRanges");
output.print(script == maxScript? " " : ", ");
output.print("// ");
output.println(scriptData.getScriptName(script));
output.println(scriptData.getName(script));
}
output.println("};");
output.println(postamble);
writeTrailer();
closeFile();
}
private static final String[] includeFiles = {"LETypes.h", "LEScripts.h", "ScriptRun.h"};
private static final String preamble =
"#include \"LETypes.h\"\n" +
"#include \"LEScripts.h\"\n" +
"#include \"ScriptRun.h\"\n" +
"\n" +
"ScriptRecord ScriptRun::scriptRecords[] = {";

View file

@ -5,14 +5,14 @@
*******************************************************************************
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/tool/layout/ScriptTagModuleWriter.java,v $
* $Date: 2003/06/03 18:49:32 $
* $Revision: 1.6 $
* $Date: 2003/12/09 01:18:11 $
* $Revision: 1.7 $
*
*******************************************************************************
*/
package com.ibm.icu.dev.tool.layout;
public class ScriptTagModuleWriter extends ModuleWriter
public class ScriptTagModuleWriter extends ScriptModuleWriter
{
private int scriptTag(String tag)
@ -32,91 +32,75 @@ public class ScriptTagModuleWriter extends ModuleWriter
super(theScriptData, theLanguageData);
}
public void writeHeaderFile(String fileName)
private void writeTagValueHeader(TagValueData data, String kind)
{
int min = scriptData.getMinScript();
int max = scriptData.getMaxScript();
openFile(fileName);
writeHeader();
output.println(hPreamble);
for (int script = min; script <= max; script += 1) {
int min = data.getMinValue();
int max = data.getMaxValue();
for (int value = min; value <= max; value += 1) {
output.print("const LETag ");
output.print(scriptData.getScriptTagLabel(script));
output.print("ScriptTag = ");
output.print(scriptData.makeScriptTag(script));
output.print(data.getTagLabel(value));
output.print(kind);
output.print("Tag = ");
output.print(data.makeTag(value));
output.print("; /* '");
output.print(scriptData.getScriptTag(script));
output.print(data.getTag(value));
output.print("' (");
output.print(scriptData.getScriptName(script));
output.print(data.getName(value));
output.println(") */");
}
}
public void writeHeaderFile(String fileName)
{
openFile(fileName);
writeHeader("__SCRIPTANDLANGUAGES_H", hIncludes);
output.println(hPreamble);
writeTagValueHeader(scriptData, "Script");
output.println(hScriptPostamble);
min = languageData.getMinLanguage();
max = languageData.getMaxLanguage();
for (int language = min; language <= max; language += 1) {
output.print("const LETag ");
output.print(languageData.getLanguageTagLabel(language));
output.print("LanguageTag = ");
output.print(languageData.makeLanguageTag(language));
output.print("; /* '");
output.print(languageData.getLanguageTag(language));
output.print("' (");
output.print(languageData.getLanguageName(language));
output.println(") */");
}
writeTagValueHeader(languageData, "Language");
output.println(hPostamble);
closeFile();
}
public void writeCPPFile(String fileName)
private void writeTagValueCPP(TagValueData data, String kind)
{
int min = scriptData.getMinScript();
int max = scriptData.getMaxScript();
int min = data.getMinValue();
int max = data.getMaxValue();
openFile(fileName);
writeHeader();
output.println(cppPreamble);
for (int script = min; script <= max; script += 1) {
String tag = scriptData.getScriptTag(script);
for (int value = min; value <= max; value += 1) {
output.print(" ");
output.print(tag);
output.print("ScriptTag");
output.print((script == max? " " : ","));
output.print(data.getTagLabel(value));
output.print(kind);
output.print("Tag");
output.print((value == max? " " : ","));
output.print(" /* '");
output.print(tag);
output.print(data.getTag(value));
output.print("' (");
output.print(scriptData.getScriptName(script));
output.print(data.getName(value));
output.println(") */");
}
}
public void writeCPPFile(String fileName)
{
openFile(fileName);
writeHeader(null, cppIncludes);
output.println(cppPreamble);
writeTagValueCPP(scriptData, "Script");
output.println(cppScriptPostamble);
min = languageData.getMinLanguage();
max = languageData.getMaxLanguage();
for (int language = min; language <= max; language += 1) {
//String tag = languageData.getLanguageTag(language);
output.print(" ");
output.print(languageData.getLanguageTagLabel(language));
output.print("LanguageTag");
output.print((language == max? " " : ","));
output.print(" /* '");
output.print(languageData.getLanguageTag(language));
output.print("' (");
output.print(languageData.getLanguageName(language));
output.println(") */");
}
writeTagValueCPP(languageData, "Language");
output.println(cppPostamble);
writeTrailer();
closeFile();
}
@ -126,18 +110,13 @@ public class ScriptTagModuleWriter extends ModuleWriter
writeCPPFile(fileName + ".cpp");
}
private static final String[] hIncludes = {"LETypes.h"};
private static final String hPreamble =
"#ifndef __SCRIPTANDLANGUAGES_H\n" +
"#define __SCRIPTANDLANGUAGES_H\n" +
"\n" +
"/**\n" +
" * \\file\n" +
" * \\internal\n" +
" */\n" +
"\n" +
"#include \"LETypes.h\"\n" +
"\n" +
"U_NAMESPACE_BEGIN\n";
" */\n";
private static final String hScriptPostamble =
"\n" +
@ -150,13 +129,10 @@ public class ScriptTagModuleWriter extends ModuleWriter
"U_NAMESPACE_END\n" +
"#endif";
private static final String[] cppIncludes =
{"LETypes.h", "ScriptAndLanguageTags.h", "OpenTypeLayoutEngine.h"};
private static final String cppPreamble =
"#include \"LETypes.h\"\n" +
"#include \"ScriptAndLanguageTags.h\"\n" +
"#include \"OpenTypeLayoutEngine.h\"\n" +
"\n" +
"U_NAMESPACE_BEGIN\n" +
"\n" +
"const LETag OpenTypeLayoutEngine::scriptTags[] = {";
private static final String cppScriptPostamble =
@ -165,7 +141,5 @@ public class ScriptTagModuleWriter extends ModuleWriter
"const LETag OpenTypeLayoutEngine::languageTags[] = {";
private static final String cppPostamble =
"};\n" +
"\n" +
"U_NAMESPACE_END";
"};\n";
}

View file

@ -0,0 +1,27 @@
/*
*******************************************************************************
* Copyright (C) 1998-2003, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
* Created on Dec 3, 2003
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/tool/layout/TagValueData.java,v $
* $Date: 2003/12/09 01:18:11 $
* $Revision: 1.1 $
*
*******************************************************************************
*/
package com.ibm.icu.dev.tool.layout;
public abstract class TagValueData
{
abstract public int getMinValue();
abstract public int getMaxValue();
abstract public String getName(int value);
abstract public String getTag(int value);
abstract public String getTagLabel(int value);
abstract public String makeTag(int value);
};

View file

@ -0,0 +1,86 @@
/*
*******************************************************************************
* Copyright (C) 1998-2003, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
* Created on Dec 3, 2003
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/tool/layout/TaggedRecord.java,v $
* $Date: 2003/12/09 01:18:12 $
* $Revision: 1.1 $
*
*******************************************************************************
*/
package com.ibm.icu.dev.tool.layout;
import java.io.*;
import java.lang.*;
import java.util.*;
import com.ibm.icu.impl.Utility;
public class TaggedRecord
{
private String tag;
public TaggedRecord(String theTag)
{
tag = theTag;
}
public String getTag()
{
return tag;
}
//
// Straight insertion sort from Knuth vol. III, pg. 81
//
public static void sort(TaggedRecord[] table, int count)
{
for (int j = 1; j < count; j += 1) {
int i;
TaggedRecord v = table[j];
String vTag = v.getTag();
for (i = j - 1; i >= 0; i -= 1) {
if (vTag.compareTo(table[i].getTag()) >= 0) {
break;
}
table[i + 1] = table[i];
}
table[i + 1] = v;
}
}
public static int search(TaggedRecord[] table, int count, String tag)
{
int log2 = Utility.highBit(count);
int power = 1 << log2;
int extra = count - power;
int probe = power;
int index = 0;
if (table[extra].getTag().compareTo(tag) <= 0) {
index = extra;
}
while (probe > (1 << 0)) {
probe >>= 1;
if (table[index + probe].getTag().compareTo(tag) <= 0) {
index += probe;
}
}
if (table[index].getTag().equals(tag)) {
return index;
}
return -1;
}
}

View file

@ -0,0 +1,23 @@
/*
*******************************************************************************
* Copyright (C) 1998-2003, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
* Created on Dec 3, 2003
*
* $Source: /xsrl/Nsvn/icu/icu4j/src/com/ibm/icu/dev/tool/layout/TreeWalker.java,v $
* $Date: 2003/12/09 01:18:11 $
* $Revision: 1.1 $
*
*******************************************************************************
*/
package com.ibm.icu.dev.tool.layout;
public abstract class TreeWalker
{
abstract void down(int ch);
abstract void up();
abstract void ligature(int lig);
abstract void done();
}