in fop-core/src/main/java/org/apache/fop/complexscripts/scripts/KhmerRenderer.java [209:371]
public String render(final String strInput) {
//Given an input String of unicode cluster to reorder.
//The return is the visual based cluster (legacy style) String.
int cursor = 0;
short state = 0;
int charCount = strInput.length();
StringBuilder result = new StringBuilder();
while (cursor < charCount) {
String reserved = "";
String signAbove = "";
String signAfter = "";
String base = "";
String robat = "";
String shifter = "";
String vowelBefore = "";
String vowelBelow = "";
String vowelAbove = "";
String vowelAfter = "";
boolean coeng = false;
String cluster;
String coeng1 = "";
String coeng2 = "";
boolean shifterAfterCoeng = false;
while (cursor < charCount) {
char curChar = strInput.charAt(cursor);
int kChar = getCharClass(curChar);
int charClass = kChar & CF_CLASS_MASK;
try {
state = khmerStateTable[state][charClass];
} catch (Exception ex) {
state = -1;
}
if (state < 0) {
break;
}
//collect variable for cluster here
if (kChar == XX) {
reserved = Character.toString(curChar);
} else if (kChar == SA) { //Sign placed above the base
signAbove = Character.toString(curChar);
} else if (kChar == SP) { //Sign placed after the base
signAfter = Character.toString(curChar);
} else if (kChar == C1 || kChar == C2 || kChar == C3) { //Consonant
if (coeng) {
if ("".equalsIgnoreCase(coeng1)) {
coeng1 = Character.toString(COENG).concat(Character.toString(curChar));
} else {
coeng2 = Character.toString(COENG).concat(Character.toString(curChar));
}
coeng = false;
} else {
base = Character.toString(curChar);
}
} else if (kChar == RB) { //Khmer sign robat u17CC
robat = Character.toString(curChar);
} else if (kChar == CS) { //Consonant-shifter
if (!"".equalsIgnoreCase(coeng1)) {
shifterAfterCoeng = true;
}
shifter = Character.toString(curChar);
} else if (kChar == DL) { //Dependent vowel placed before the base
vowelBefore = Character.toString(curChar);
} else if (kChar == DB) { //Dependent vowel placed below the base
vowelBelow = Character.toString(curChar);
} else if (kChar == DA) { //Dependent vowel placed above the base
vowelAbove = Character.toString(curChar);
} else if (kChar == DR) { //Dependent vowel placed behind the base
vowelAfter = Character.toString(curChar);
} else if (kChar == CO) { //Khmer combining mark COENG
coeng = true;
} else if (kChar == VA) { //Khmer split vowel, see da
vowelBefore = Character.toString(SRAE);
vowelAbove = Character.toString(strEcombining(curChar));
} else if (kChar == VR) { //Khmer split vowel, see dr
vowelBefore = Character.toString(SRAE);
vowelAfter = Character.toString(strEcombining(curChar));
}
cursor += 1;
}
// end of while (a cluster has found)
// logic when cluster has coeng
// should coeng be located on left side
String coengBefore = "";
if (CORO.equalsIgnoreCase(coeng1)) {
coengBefore = coeng1;
coeng1 = "";
} else if (CORO.equalsIgnoreCase(coeng2)) {
coengBefore = coeng2;
coeng2 = "";
}
//logic of shifter with base character
if (!"".equalsIgnoreCase(base) && !"".equalsIgnoreCase(shifter)) {
if (!"".equalsIgnoreCase(vowelAbove)) {
shifter = "";
vowelBelow = Character.toString(SRAU);
}
}
// uncomplete coeng
if (coeng && "".equalsIgnoreCase(coeng1)) {
coeng1 = Character.toString(COENG);
} else if (coeng && "".equalsIgnoreCase(coeng2)) {
coeng2 = Character.toString(MARK).concat(Character.toString(COENG));
}
//place of shifter
String shifter1 = "";
String shifter2 = "";
if (shifterAfterCoeng) {
shifter2 = shifter;
} else {
shifter1 = shifter;
}
boolean specialCaseBA = false;
String strMARKSRAAA = Character.toString(MARK).concat(Character.toString(SRAAA));
String strMARKSRAAU = Character.toString(MARK).concat(Character.toString(SRAAU));
if (Character.toString(BA).equalsIgnoreCase(base)
&& (Character.toString(SRAAA).equalsIgnoreCase(vowelAfter)
|| Character.toString(SRAAU).equalsIgnoreCase(vowelAfter)
|| strMARKSRAAA.equalsIgnoreCase(vowelAfter) || strMARKSRAAU.equalsIgnoreCase(vowelAfter))) {
specialCaseBA = true;
if (!"".equalsIgnoreCase(coeng1)) {
String coeng1Complete = coeng1.substring(0, coeng1.length() - 1);
if (Character.toString(BA).equalsIgnoreCase(coeng1Complete)
|| Character.toString(YO).equalsIgnoreCase(coeng1Complete)
|| Character.toString(SA_C).equalsIgnoreCase(coeng1Complete)) {
specialCaseBA = false;
}
}
}
// cluster formation
if (specialCaseBA) {
cluster = vowelBefore + coengBefore + base + vowelAfter + robat + shifter1 + coeng1 + coeng2
+ shifter2 + vowelBelow + vowelAbove + signAbove + signAfter;
} else {
cluster = vowelBefore + coengBefore + base + robat + shifter1 + coeng1 + coeng2 + shifter2
+ vowelBelow + vowelAbove + vowelAfter + signAbove + signAfter;
}
result.append(cluster + reserved);
state = 0;
//end of while
}
return result.toString();
}