3
\$\begingroup\$

Prior to Android 6.0, Mongolian text is not supported on Android devices. And as far as I know, OpenType smart font rendering is still not supported. Therefore, in all my Mongolian apps I use a rendering class to convert Unicode text to the appropriate PUA glyph based on the context.

The following is the main method of the class (full class on GitHub here):

public String unicodeToGlyphs(String inputString) {
    StringBuilder outputString = new StringBuilder();
    StringBuilder subString = new StringBuilder();

    if (inputString == null || inputString.length() == 0) {
        return "";
    }

    // Loop through characters in string
    boolean isMongolSubString = isMongolian(inputString.charAt(0));
    for (char character : inputString.toCharArray()) {

        if (isMongolian(character) || character == Uni.NNBS || character== CURSOR_HOLDER) {

            if (!isMongolSubString) {
                outputString.append(subString.toString());
                subString.setLength(0);
            }

            subString.append(character);
            isMongolSubString = true;

        } else { // non-Mongol character

            if (isMongolSubString) {

                // XXX This is not DRY code, see below
                // break up word from suffixes
                String[] parts = subString.toString().split(String.valueOf(Uni.NNBS), -1);
                for (int j = 0; j < parts.length; j++) {
                    if (j == 0) { // this is the main word
                        // Convert mongol word to glyphs and add to output string
                        outputString.append(convertWord(parts[j]));
                    } else { // these are the suffixes
                        // remove the cursor holder character
                        String tempSuffix = parts[j].replace(String.valueOf(CURSOR_HOLDER), "");
                        outputString.append(Uni.NNBS);
                        if (mSuffixMap.containsKey(tempSuffix)) {
                            outputString.append(mSuffixMap.get(tempSuffix));
                            if (parts[j].contains(String.valueOf(CURSOR_HOLDER))) {
                                outputString.append(CURSOR_HOLDER);
                            }
                        } else {
                            outputString.append(convertWord(parts[j]));
                        }
                    }
                }


                // reset substring
                subString.setLength(0);
                subString.append(character);

            } else {
                // Add nonMongol chars to string
                subString.append(character);
            }
            isMongolSubString = false;
        }
    }

    // Add any final substring
    if (subString.length() > 0) {
        if (isMongolSubString) {


            // XXX This is not DRY code, see above
            // break up word from suffixes
            String[] parts = subString.toString().split(String.valueOf(Uni.NNBS), -1);
            for (int j = 0; j < parts.length; j++) {
                if (j == 0) { // this is the main word
                    // Convert mongol word to glyphs and add to output string
                    outputString.append(convertWord(parts[j]));
                } else { // these are the suffixes
                    String tempSuffix = parts[j].replace(String.valueOf(CURSOR_HOLDER), "");
                    outputString.append(Uni.NNBS);
                    if (mSuffixMap.containsKey(tempSuffix)) {
                        outputString.append(mSuffixMap.get(tempSuffix));
                        if (parts[j].contains(String.valueOf(CURSOR_HOLDER))) {
                            outputString.append(CURSOR_HOLDER);
                        }
                    } else {
                        outputString.append(convertWord(parts[j]));
                    }
                }
            }


        } else {
            // Add nonMongol chars to string
            outputString.append(subString.toString());
        }
    }

    return outputString.toString();
}

Area of concern:

I repeat the following code block. I know its not good to repeat myself but if I break this off into another method, I will either have to make a class variable (adding unnecessary state is bad, too, right?) or modify a method parameter in place (which I understand is generally not a good idea).

// break up word from suffixes
String[] parts = subString.toString().split(String.valueOf(Uni.NNBS), -1);
for (int j = 0; j < parts.length; j++) {
    if (j == 0) { // this is the main word
        // Convert mongol word to glyphs and add to output string
        outputString.append(convertWord(parts[j]));
    } else { // these are the suffixes
        String tempSuffix = parts[j].replace(String.valueOf(CURSOR_HOLDER), "");
        outputString.append(Uni.NNBS);
        if (mSuffixMap.containsKey(tempSuffix)) {
            outputString.append(mSuffixMap.get(tempSuffix));
            if (parts[j].contains(String.valueOf(CURSOR_HOLDER))) {
                outputString.append(CURSOR_HOLDER);
            }
        } else {
            outputString.append(convertWord(parts[j]));
        }
    }
}
\$\endgroup\$

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.