in fop-core/src/main/codegen/unicode/java/org/apache/fop/text/linebreak/GenerateLineBreakUtils.java [86:482]
private static void convertLineBreakProperties(
String lineBreakFileName,
String propertyValueFileName,
String breakPairFileName,
String outFileName)
throws Exception {
readLineBreakProperties(lineBreakFileName, propertyValueFileName);
// read break pair table
int lineBreakPropertyValueCount = lineBreakPropertyValues.size();
int tableSize = lineBreakPropertyValueCount - NOT_IN_PAIR_TABLE.length;
Map notInPairTableMap = new HashMap(NOT_IN_PAIR_TABLE.length);
for (int i = 0; i < NOT_IN_PAIR_TABLE.length; i++) {
Object v = lineBreakPropertyValues.get(NOT_IN_PAIR_TABLE[i]);
if (v == null) {
throw new Exception("'not in pair table' property not found: " + NOT_IN_PAIR_TABLE[i]);
}
notInPairTableMap.put(NOT_IN_PAIR_TABLE[i], v);
}
byte[][] pairTable = new byte[tableSize][];
byte[] columnHeader = new byte[tableSize];
byte[] rowHeader = new byte[tableSize];
byte[] columnMap = new byte[lineBreakPropertyValueCount + 1];
Arrays.fill(columnMap, (byte)255);
byte[] rowMap = new byte[lineBreakPropertyValueCount + 1];
Arrays.fill(rowMap, (byte)255);
BufferedReader b = new BufferedReader(new FileReader(breakPairFileName));
String line = b.readLine();
int lineNumber = 1;
String[] lineTokens;
String name;
// read header
if (line != null) {
lineTokens = line.split("\\s+");
byte columnNumber = 0;
for (int i = 0; i < lineTokens.length; ++i) {
name = lineTokens[i];
if (name.length() > 0) {
if (columnNumber >= columnHeader.length) {
throw new Exception(breakPairFileName + ':' + lineNumber + ": unexpected column header " + name);
}
if (notInPairTableMap.get(name) != null) {
throw new Exception(breakPairFileName + ':' + lineNumber + ": invalid column header " + name);
}
Byte v = (Byte)lineBreakPropertyValues.get(name);
if (v != null) {
byte vv = v.byteValue();
columnHeader[columnNumber] = vv;
columnMap[vv] = columnNumber;
} else {
throw new Exception(breakPairFileName + ':' + lineNumber + ": unknown column header " + name);
}
columnNumber++;
}
}
if (columnNumber < columnHeader.length) {
StringBuffer missing = new StringBuffer();
for (int j = 0; j < lineBreakPropertyShortNames.size(); j++) {
boolean found = false;
for (int k = 0; k < columnNumber; k++) {
if (columnHeader[k] == j + 1) {
found = true;
break;
}
}
if (!found) {
if (missing.length() > 0) {
missing.append(", ");
}
missing.append((String)lineBreakPropertyShortNames.get(j));
}
}
throw new Exception(
breakPairFileName + ':' + lineNumber + ": missing column for properties: " + missing.toString());
}
} else {
throw new Exception(breakPairFileName + ':' + lineNumber + ": can't read table header");
}
line = b.readLine().trim();
lineNumber++;
byte rowNumber = 0;
while (line != null && line.length() > 0) {
if (rowNumber >= rowHeader.length) {
throw new Exception(breakPairFileName + ':' + lineNumber + ": unexpected row " + line);
}
pairTable[rowNumber] = new byte[tableSize];
lineTokens = line.split("\\s+");
if (lineTokens.length > 0) {
name = lineTokens[0];
if (notInPairTableMap.get(name) != null) {
throw new Exception(breakPairFileName + ':' + lineNumber + ": invalid row header " + name);
}
Byte v = (Byte)lineBreakPropertyValues.get(name);
if (v != null) {
byte vv = v.byteValue();
rowHeader[rowNumber] = vv;
rowMap[vv] = rowNumber;
} else {
throw new Exception(breakPairFileName + ':' + lineNumber + ": unknown row header " + name);
}
} else {
throw new Exception(breakPairFileName + ':' + lineNumber + ": can't read row header");
}
int columnNumber = 0;
String token;
for (int i = 1; i < lineTokens.length; ++i) {
token = lineTokens[i];
if (token.length() == 1) {
byte tokenBreakClass = (byte)BREAK_CLASS_TOKENS.indexOf(token.charAt(0));
if (tokenBreakClass >= 0) {
pairTable[rowNumber][columnNumber] = tokenBreakClass;
} else {
throw new Exception(breakPairFileName + ':' + lineNumber + ": unexpected token: " + token);
}
} else {
throw new Exception(breakPairFileName + ':' + lineNumber + ": token too long: " + token);
}
columnNumber++;
}
line = b.readLine().trim();
lineNumber++;
rowNumber++;
}
if (rowNumber < rowHeader.length) {
StringBuffer missing = new StringBuffer();
for (int j = 0; j < lineBreakPropertyShortNames.size(); j++) {
boolean found = false;
for (int k = 0; k < rowNumber; k++) {
if (rowHeader[k] == j + 1) {
found = true;
break;
}
}
if (!found) {
if (missing.length() > 0) {
missing.append(", ");
}
missing.append((String)lineBreakPropertyShortNames.get(j));
}
}
throw new Exception(
breakPairFileName + ':' + lineNumber + ": missing row for properties: " + missing.toString());
}
// generate class
int rowsize = 512;
int blocksize = lineBreakProperties.length / rowsize;
byte[][] row = new byte[rowsize][];
int idx = 0;
StringBuffer doStaticLinkCode = new StringBuffer();
PrintWriter out = new PrintWriter(new FileWriter(outFileName));
License.writeJavaLicenseId(out);
out.println();
out.println("package org.apache.fop.text.linebreak;");
out.println();
out.println("/*");
out.println(" * !!! THIS IS A GENERATED FILE !!!");
out.println(" * If updates to the source are needed, then:");
out.println(" * - apply the necessary modifications to");
out.println(" * 'src/codegen/unicode/java/org/apache/fop/text/linebreak/GenerateLineBreakUtils.java'");
out.println(" * - run 'ant codegen-unicode', which will generate a new LineBreakUtils.java");
out.println(" * in 'src/java/org/apache/fop/text/linebreak'");
out.println(" * - commit BOTH changed files");
out.println(" */");
out.println();
out.println("// CSOFF: WhitespaceAfterCheck");
out.println("// CSOFF: LineLengthCheck");
out.println();
out.println("/** Line breaking utilities. */");
out.println("public final class LineBreakUtils {");
out.println();
out.println(" private LineBreakUtils() {");
out.println(" }");
out.println();
out.println(" /** Break class constant */");
out.println(" public static final byte DIRECT_BREAK = " + DIRECT_BREAK + ';');
out.println(" /** Break class constant */");
out.println(" public static final byte INDIRECT_BREAK = " + INDIRECT_BREAK + ';');
out.println(" /** Break class constant */");
out.println(" public static final byte COMBINING_INDIRECT_BREAK = " + COMBINING_INDIRECT_BREAK + ';');
out.println(" /** Break class constant */");
out.println(" public static final byte COMBINING_PROHIBITED_BREAK = " + COMBINING_PROHIBITED_BREAK + ';');
out.println(" /** Break class constant */");
out.println(" public static final byte PROHIBITED_BREAK = " + PROHIBITED_BREAK + ';');
out.println(" /** Break class constant */");
out.println(" public static final byte EXPLICIT_BREAK = " + EXPLICIT_BREAK + ';');
out.println();
out.println(" private static final byte[][] PAIR_TABLE = {");
boolean printComma = false;
for (int i = 1; i <= lineBreakPropertyValueCount; i++) {
if (printComma) {
out.println(",");
} else {
printComma = true;
}
out.print(" {");
boolean localPrintComma = false;
for (int j = 1; j <= lineBreakPropertyValueCount; j++) {
if (localPrintComma) {
out.print(", ");
} else {
localPrintComma = true;
}
if (columnMap[j] != -1 && rowMap[i] != -1) {
out.print(pairTable[rowMap[i]][columnMap[j]]);
} else {
out.print('0');
}
}
out.print('}');
}
out.println("};");
out.println();
out.println(" private static byte[][] lineBreakProperties = new byte[" + rowsize + "][];");
out.println();
out.println(" private static void init0() {");
int rowsPrinted = 0;
int initSections = 0;
for (int i = 0; i < rowsize; i++) {
boolean found = false;
for (int j = 0; j < i; j++) {
if (row[j] != null) {
boolean matched = true;
for (int k = 0; k < blocksize; k++) {
if (row[j][k] != lineBreakProperties[idx + k]) {
matched = false;
break;
}
}
if (matched) {
found = true;
doStaticLinkCode.append(" lineBreakProperties[");
doStaticLinkCode.append(i);
doStaticLinkCode.append("] = lineBreakProperties[");
doStaticLinkCode.append(j);
doStaticLinkCode.append("];\n");
break;
}
}
}
if (!found) {
if (rowsPrinted >= 64) {
out.println(" }");
out.println();
initSections++;
out.println(" private static void init" + initSections + "() {");
rowsPrinted = 0;
}
row[i] = new byte[blocksize];
boolean printLocalComma = false;
out.print(" lineBreakProperties[" + i + "] = new byte[] { ");
for (int k = 0; k < blocksize; k++) {
row[i][k] = lineBreakProperties[idx + k];
if (printLocalComma) {
out.print(", ");
} else {
printLocalComma = true;
}
out.print(row[i][k]);
}
out.println("};");
rowsPrinted++;
}
idx += blocksize;
}
out.println(" }");
out.println();
out.println(" static {");
for (int i = 0; i <= initSections; i++) {
out.println(" init" + i + "();");
}
out.print(doStaticLinkCode);
out.println(" }");
out.println();
for (int i = 0; i < lineBreakPropertyShortNames.size(); i++) {
String shortName = (String)lineBreakPropertyShortNames.get(i);
out.println(" /** Linebreak property constant */");
out.print(" public static final byte LINE_BREAK_PROPERTY_");
out.print(shortName);
out.print(" = ");
out.print(i + 1);
out.println(';');
}
out.println();
final String shortNamePrefix = " private static String[] lineBreakPropertyShortNames = {";
out.print(shortNamePrefix);
int lineLength = shortNamePrefix.length();
printComma = false;
for (int i = 0; i < lineBreakPropertyShortNames.size(); i++) {
name = (String)lineBreakPropertyShortNames.get(i);
if (printComma) {
if (lineLength <= MAX_LINE_LENGTH - 2) {
out.print(", ");
} else {
out.print(",");
}
// count the space anyway to force a linebreak if the comma causes lineLength == MAX_LINE_LENGTH
lineLength += 2;
} else {
printComma = true;
}
if (lineLength > MAX_LINE_LENGTH) {
out.println();
out.print(" ");
lineLength = 8;
}
out.print('"');
out.print(name);
out.print('"');
lineLength += (2 + name.length());
}
out.println("};");
out.println();
final String longNamePrefix = " private static String[] lineBreakPropertyLongNames = {";
out.print(longNamePrefix);
lineLength = longNamePrefix.length();
printComma = false;
for (int i = 0; i < lineBreakPropertyLongNames.size(); i++) {
name = (String)lineBreakPropertyLongNames.get(i);
if (printComma) {
out.print(',');
lineLength++;
} else {
printComma = true;
}
if (lineLength > MAX_LINE_LENGTH) {
out.println();
out.print(" ");
lineLength = 8;
}
out.print('"');
out.print(name);
out.print('"');
lineLength += (2 + name.length());
}
out.println("};");
out.println();
out.println(" /**");
out.println(" * Return the short name for the linebreak property corresponding");
out.println(" * to the given symbolic constant.");
out.println(" *");
out.println(" * @param i the numeric value of the linebreak property");
out.println(" * @return the short name of the linebreak property");
out.println(" */");
out.println(" public static String getLineBreakPropertyShortName(byte i) {");
out.println(" if (i > 0 && i <= lineBreakPropertyShortNames.length) {");
out.println(" return lineBreakPropertyShortNames[i - 1];");
out.println(" } else {");
out.println(" return null;");
out.println(" }");
out.println(" }");
out.println();
out.println(" /**");
out.println(" * Return the long name for the linebreak property corresponding");
out.println(" * to the given symbolic constant.");
out.println(" *");
out.println(" * @param i the numeric value of the linebreak property");
out.println(" * @return the long name of the linebreak property");
out.println(" */");
out.println(" public static String getLineBreakPropertyLongName(byte i) {");
out.println(" if (i > 0 && i <= lineBreakPropertyLongNames.length) {");
out.println(" return lineBreakPropertyLongNames[i - 1];");
out.println(" } else {");
out.println(" return null;");
out.println(" }");
out.println(" }");
out.println();
out.println(" /**");
out.println(" * Return the linebreak property constant for the given <code>char</code>");
out.println(" *");
out.println(" * @param c the <code>char</code> whose linebreak property to return");
out.println(" * @return the constant representing the linebreak property");
out.println(" */");
out.println(" public static byte getLineBreakProperty(char c) {");
out.println(" return lineBreakProperties[c / " + blocksize + "][c % " + blocksize + "];");
out.println(" }");
out.println();
out.println(" /**");
out.println(" * Return the break class constant for the given pair of linebreak");
out.println(" * property constants.");
out.println(" *");
out.println(" * @param lineBreakPropertyBefore the linebreak property for the first character");
out.println(" * in a two-character sequence");
out.println(" * @param lineBreakPropertyAfter the linebreak property for the second character");
out.println(" * in a two-character sequence");
out.println(" * @return the constant representing the break class");
out.println(" */");
out.println(
" public static byte getLineBreakPairProperty(int lineBreakPropertyBefore, int lineBreakPropertyAfter) {");
out.println(" return PAIR_TABLE[lineBreakPropertyBefore - 1][lineBreakPropertyAfter - 1];");
out.println(" }");
out.println();
out.println("}");
out.flush();
out.close();
}