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\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.