Java tutorial
//package com.java2s; //License from project: Open Source License import java.util.regex.Pattern; public class Main { private static final Pattern patternBreakingWebView = Pattern.compile("[" + "\\u0627" + "\\u0600\\u0601\\u0602\\u0603\\u0606\\u0607\\u0608\\u0609\\u060A\\u060B\\u060D\\u060E" + "\\u0610\\u0611\\u0612\\u0613\\u0614\\u0615\\u0616\\u0617\\u0618\\u0619\\u061A\\u061B\\u061E\\u061F" + "\\u0621" + "\\u063B\\u063C\\u063D\\u063E\\u063F" + "\\u0640\\u064B\\u064C\\u064D\\u064E\\u064F" + "\\u0650\\u0651\\u0652\\u0653\\u0654\\u0655\\u0656\\u0657\\u0658\\u0659\\u065A\\u065B\\u065C\\u065D\\u065E" + "\\u0660\\u066A\\u066B\\u066C\\u066F\\u0670\\u0672'" + "\\u06D4\\u06D5\\u06D6\\u06D7\\u06D8\\u06D9\\u06DA\\u06DB\\u06DC\\u06DF" + "\\u06E0\\u06E1\\u06E2\\u06E3\\u06E4\\u06E5\\u06E6\\u06E7\\u06E8\\u06E9\\u06EA\\u06EB\\u06EC\\u06ED\\u06EE\\u06EF" + "\\u06D6\\u06D7\\u06D8\\u06D9\\u06DA\\u06DB\\u06DC\\u06DD\\u06DE\\u06DF" + "\\u06F0\\u06FD" + "\\uFE70\\uFE71\\uFE72\\uFE73\\uFE74\\uFE75\\uFE76\\uFE77\\uFE78\\uFE79\\uFE7A\\uFE7B\\uFE7C\\uFE7D\\uFE7E\\uFE7F" + "\\uFC5E\\uFC5F\\uFC60\\uFC61\\uFC62\\uFC63" + "]"); public static StringBuffer manualRTL(StringBuffer text, boolean forWebView) { if (forWebView) { if (patternBreakingWebView.matcher(text).find()) { // handle BiDi manually // global direction is LTR because of HTML markup StringBuffer ltr = new StringBuffer(""), rtl = new StringBuffer(""); int i = 0; while (i < text.length()) { char c = text.charAt(i); if (isStrongLeftToRight(c) || !isStrongRightToLeft(c)) { while (i < text.length() && !isStrongRightToLeft(text.charAt(i))) { ltr.append(text.charAt(i)); i++; } if (i == text.length()) { break; } } if (isStrongRightToLeft(text.charAt(i))) { while (i < text.length() && !isStrongLeftToRight(text.charAt(i))) { // additional end condition: start of an HTML tag if (text.charAt(i) == '<') { break; } rtl.append(text.charAt(i)); i++; } // reverse only words that Android will not display correctly by itself if (patternBreakingWebView.matcher(rtl).find()) { ltr.append(rtl.reverse()); } else { ltr.append(rtl); } rtl = new StringBuffer(""); } } return ltr; } } return text; } public static boolean isStrongLeftToRight(char c) { byte dir = Character.getDirectionality(c); return (dir == Character.DIRECTIONALITY_LEFT_TO_RIGHT) || (dir == Character.DIRECTIONALITY_LEFT_TO_RIGHT_EMBEDDING) || (dir == Character.DIRECTIONALITY_LEFT_TO_RIGHT_OVERRIDE); } public static boolean isStrongRightToLeft(char c) { byte dir = Character.getDirectionality(c); return (dir == Character.DIRECTIONALITY_RIGHT_TO_LEFT) || (dir == Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC) || (dir == Character.DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING) || (dir == Character.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE); } }