mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-15 17:56:54 +00:00
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:
parent
648a43a3d8
commit
4e6e5b433f
27 changed files with 2544 additions and 277 deletions
360
icu4j/src/com/ibm/icu/dev/tool/layout/ArabicGSUBBuilder.java
Normal file
360
icu4j/src/com/ibm/icu/dev/tool/layout/ArabicGSUBBuilder.java
Normal 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]);
|
||||
}
|
||||
}
|
127
icu4j/src/com/ibm/icu/dev/tool/layout/ArabicShaping.java
Normal file
127
icu4j/src/com/ibm/icu/dev/tool/layout/ArabicShaping.java
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
120
icu4j/src/com/ibm/icu/dev/tool/layout/CharacterData.java
Normal file
120
icu4j/src/com/ibm/icu/dev/tool/layout/CharacterData.java
Normal 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;
|
||||
}
|
247
icu4j/src/com/ibm/icu/dev/tool/layout/ClassTable.java
Normal file
247
icu4j/src/com/ibm/icu/dev/tool/layout/ClassTable.java
Normal 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
142
icu4j/src/com/ibm/icu/dev/tool/layout/FeatureList.java
Normal file
142
icu4j/src/com/ibm/icu/dev/tool/layout/FeatureList.java
Normal 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();
|
||||
}
|
||||
}
|
58
icu4j/src/com/ibm/icu/dev/tool/layout/GDEFWriter.java
Normal file
58
icu4j/src/com/ibm/icu/dev/tool/layout/GDEFWriter.java
Normal 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");
|
||||
}
|
||||
}
|
69
icu4j/src/com/ibm/icu/dev/tool/layout/GSUBWriter.java
Normal file
69
icu4j/src/com/ibm/icu/dev/tool/layout/GSUBWriter.java
Normal 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");
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
46
icu4j/src/com/ibm/icu/dev/tool/layout/LigatureEntry.java
Normal file
46
icu4j/src/com/ibm/icu/dev/tool/layout/LigatureEntry.java
Normal 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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
230
icu4j/src/com/ibm/icu/dev/tool/layout/LigatureTree.java
Normal file
230
icu4j/src/com/ibm/icu/dev/tool/layout/LigatureTree.java
Normal 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();
|
||||
}
|
||||
}
|
150
icu4j/src/com/ibm/icu/dev/tool/layout/LigatureTreeWalker.java
Normal file
150
icu4j/src/com/ibm/icu/dev/tool/layout/LigatureTreeWalker.java
Normal 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);
|
||||
}
|
||||
}
|
96
icu4j/src/com/ibm/icu/dev/tool/layout/Lookup.java
Normal file
96
icu4j/src/com/ibm/icu/dev/tool/layout/Lookup.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
65
icu4j/src/com/ibm/icu/dev/tool/layout/LookupList.java
Normal file
65
icu4j/src/com/ibm/icu/dev/tool/layout/LookupList.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
24
icu4j/src/com/ibm/icu/dev/tool/layout/LookupSubtable.java
Normal file
24
icu4j/src/com/ibm/icu/dev/tool/layout/LookupSubtable.java
Normal 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);
|
||||
}
|
|
@ -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";
|
||||
|
||||
}
|
||||
|
|
132
icu4j/src/com/ibm/icu/dev/tool/layout/OpenTypeTableWriter.java
Normal file
132
icu4j/src/com/ibm/icu/dev/tool/layout/OpenTypeTableWriter.java
Normal 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);
|
||||
}
|
|
@ -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";
|
||||
|
|
109
icu4j/src/com/ibm/icu/dev/tool/layout/ScriptIDModuleWriter.java
Normal file
109
icu4j/src/com/ibm/icu/dev/tool/layout/ScriptIDModuleWriter.java
Normal 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";
|
||||
}
|
208
icu4j/src/com/ibm/icu/dev/tool/layout/ScriptList.java
Normal file
208
icu4j/src/com/ibm/icu/dev/tool/layout/ScriptList.java
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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[] = {";
|
||||
|
||||
|
|
|
@ -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";
|
||||
}
|
27
icu4j/src/com/ibm/icu/dev/tool/layout/TagValueData.java
Normal file
27
icu4j/src/com/ibm/icu/dev/tool/layout/TagValueData.java
Normal 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);
|
||||
};
|
86
icu4j/src/com/ibm/icu/dev/tool/layout/TaggedRecord.java
Normal file
86
icu4j/src/com/ibm/icu/dev/tool/layout/TaggedRecord.java
Normal 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;
|
||||
}
|
||||
}
|
||||
|
23
icu4j/src/com/ibm/icu/dev/tool/layout/TreeWalker.java
Normal file
23
icu4j/src/com/ibm/icu/dev/tool/layout/TreeWalker.java
Normal 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();
|
||||
}
|
Loading…
Add table
Reference in a new issue