diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/LanguageUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/LanguageUtils.java index 4dfb7453c..279448b47 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/LanguageUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/LanguageUtils.java @@ -18,6 +18,7 @@ package nodomain.freeyourgadget.gadgetbridge.util; import android.text.TextUtils; +import android.util.Log; import org.apache.commons.lang3.text.WordUtils; @@ -182,6 +183,8 @@ public class LanguageUtils { if (s == null || s.isEmpty()){ return s; } + Log.d("ROIGR", "before: |" + org.apache.commons.lang3.StringEscapeUtils.escapeJava(s) + "|"); + int length = s.length(); String oldString = s.substring(0, length); String newString = ""; @@ -191,51 +194,81 @@ public class LanguageUtils { int startPos = 0; int endPos = 0; - Boolean isRtlState = RtlUtils.isRtl(oldString.charAt(0)); + RtlUtils.characterType CurRtlType = RtlUtils.isRtl(oldString.charAt(0))? RtlUtils.characterType.rtl : RtlUtils.characterType.ltr; + RtlUtils.characterType PhraseRtlType = CurRtlType; + char c; - String line = ""; +// String word = "", phrase = "", line = ""; + StringBuilder word = new StringBuilder(); + StringBuilder phrase = new StringBuilder(); + StringBuilder line = new StringBuilder(); + String phraseString = ""; + for (int i = 0; i < length; i++) { c = oldString.charAt(i); - if ((RtlUtils.isRtl(c) == isRtlState || RtlUtils.isPunctuations(c)) && i < length - 1) { - endPos++; + + Log.d("ROIGR", "char: " + c + " :" + Character.getDirectionality(c)); +// Log.d("ROIGR", "hex : " + (int)c); + + if (RtlUtils.isLtr(c)){ + CurRtlType = RtlUtils.characterType.ltr; + } else if (RtlUtils.isRtl(c)) { + CurRtlType = RtlUtils.characterType.rtl; + } + + if ((CurRtlType == PhraseRtlType) || RtlUtils.isPunctuations(c)) { + word.append(c); } else { - String word; + if (RtlUtils.isSpaceSign(c)){ + word.append(c); - if (RtlUtils.isWordEndSign(c)){ - endPos++; - } - - if (i == length - 1){ - endPos = length; - } - word = oldString.substring(startPos, endPos); - if (isRtlState) { - if(RtlUtils.contextualSupport()){ - word = RtlUtils.converToContextual(word); + if (line.length() + phrase.length() + word.length() < line_max_size) { + phrase.append(word); + word.setLength(0); + continue; } - word = RtlUtils.reverse(word); } + + //we either move from rtl to ltr or vice versa or word should move to new line + + phraseString = phrase.toString(); + if (PhraseRtlType == RtlUtils.characterType.rtl) { + if(RtlUtils.contextualSupport()){ + phraseString = RtlUtils.converToContextual(phraseString); + } + phraseString = RtlUtils.reverse(phraseString); + } + line.insert(0, phraseString); + phrase.setLength(0); + + Log.d("ROIGR", "word: |" + word + "|"); if (line.length() + word.length() > line_max_size) { - lines.add(line + "\n"); - line = ""; + line.append('\n'); + lines.add(line.toString()); + Log.d("ROIGR", "line: |" + line + "|"); + line.setLength(0); } - line = String.format("%s%s", word, line); - if (line.endsWith("\0") || line.endsWith("\n")) { + + + + if (RtlUtils.isEndLineSign(c)) { lines.add(line); + Log.d("ROIGR", "line: |" + line + "|"); line = ""; } - startPos = endPos; - if (!RtlUtils.isWordEndSign(c)){ - endPos++; - isRtlState = !isRtlState; + if (!RtlUtils.isSpaceSign(c)){ + word.append(c); + PhraseRtlType = PhraseRtlType == RtlUtils.characterType.rtl ? RtlUtils.characterType.ltr : RtlUtils.characterType.rtl; } } } - lines.add(line); + lines.add(line.toString()); newString = TextUtils.join("", lines); + Log.d("ROIGR", "after : |" + org.apache.commons.lang3.StringEscapeUtils.escapeJava(newString) + "|"); + return newString; } } diff --git a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/RtlUtils.java b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/RtlUtils.java index a7aa5944d..52697b8c6 100644 --- a/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/RtlUtils.java +++ b/app/src/main/java/nodomain/freeyourgadget/gadgetbridge/util/RtlUtils.java @@ -10,6 +10,45 @@ import java.util.Map; import nodomain.freeyourgadget.gadgetbridge.GBApplication; class RtlUtils { + + enum characterType{ + ltr, + rtl, + rtl_arabic, + punctuation, + lineEnd, + space, + } + + public static characterType getCharacterType(char c){ + characterType type; + switch (Character.getDirectionality(c)) { + case Character.DIRECTIONALITY_RIGHT_TO_LEFT: + type = characterType.rtl; + break; + case Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC: + type = characterType.rtl_arabic; + break; + case Character.DIRECTIONALITY_EUROPEAN_NUMBER_SEPARATOR: + case Character.DIRECTIONALITY_EUROPEAN_NUMBER_TERMINATOR: + case Character.DIRECTIONALITY_COMMON_NUMBER_SEPARATOR: + case Character.DIRECTIONALITY_OTHER_NEUTRALS: + type = characterType.punctuation; + break; + case Character.DIRECTIONALITY_BOUNDARY_NEUTRAL: + case Character.DIRECTIONALITY_PARAGRAPH_SEPARATOR: + type = characterType.lineEnd; + break; + case Character.DIRECTIONALITY_WHITESPACE: + type = characterType.space; + break; + default: + type = characterType.ltr; + } + + return type; + } + /** * Checks the status of right-to-left option * @return true if right-to-left option is On, and false, if Off or not exist @@ -58,37 +97,53 @@ class RtlUtils { /** * @return true if the char is in the rtl range, otherwise false */ - static Boolean isHebrew(char c){ - for (Pair rang: hebrewRange) { - if (rang.first <= c && c <= rang.second) { - return true; - } - } - return false; + static boolean isHebrew(char c){ +// for (Pair rang: hebrewRange) { +// if (rang.first <= c && c <= rang.second) { +// return true; +// } +// } +// return false; + return getCharacterType(c) == characterType.rtl; } /** * @return true if the char is in the rtl range, otherwise false */ - static Boolean isArabic(char c){ - for (Pair rang: arabicRange) { - if (rang.first <= c && c <= rang.second) { - return true; - } - } - return false; + static boolean isArabic(char c){ +// for (Pair rang: arabicRange) { +// if (rang.first <= c && c <= rang.second) { +// return true; +// } +// } +// return false; + return getCharacterType(c) == characterType.rtl_arabic; } /** * @return true if the char is in the rtl range, otherwise false */ - static Boolean isRtl(char c){ - for (Pair rang: rtlRange) { - if (rang.first <= c && c <= rang.second) { - return true; - } - } - return false; + static boolean isLtr(char c){ +// for (Pair rang: rtlRange) { +// if (rang.first <= c && c <= rang.second) { +// return true; +// } +// } +// return false; + return getCharacterType(c) == characterType.ltr; + } + + /** + * @return true if the char is in the rtl range, otherwise false + */ + static boolean isRtl(char c){ +// for (Pair rang: rtlRange) { +// if (rang.first <= c && c <= rang.second) { +// return true; +// } +// } +// return false; + return (getCharacterType(c) == characterType.rtl) || (getCharacterType(c) == characterType.rtl_arabic); } //list of unicode ranges of punctuations chars @@ -104,13 +159,14 @@ class RtlUtils { /** * @return true if the char is in the punctuations range, otherwise false */ - static Boolean isPunctuations(char c){ - for (Pair rang: punctuationsRange) { - if (rang.first <= c && c <= rang.second) { - return true; - } - } - return false; + static boolean isPunctuations(char c){ +// for (Pair rang: punctuationsRange) { +// if (rang.first <= c && c <= rang.second) { +// return true; +// } +// } +// return false; + return getCharacterType(c) == characterType.punctuation; } //list of sign that ends a word @@ -125,14 +181,15 @@ class RtlUtils { /** * @return true if the char is in the end of word list, otherwise false */ - static Boolean isWordEndSign(char c){ - for (char sign: wordEndSigns){ - if (c == sign){ - return true; - } - } - - return false; + static boolean isSpaceSign(char c){ +// for (char sign: wordEndSigns){ +// if (c == sign){ +// return true; +// } +// } +// +// return false; + return getCharacterType(c) == characterType.space; } //list of sign that ends a word @@ -146,14 +203,15 @@ class RtlUtils { /** * @return true if the char is in the end of word list, otherwise false */ - static Boolean isEndLineSign(char c){ - for (char sign: endLineSigns){ - if (c == sign){ - return true; - } - } - - return false; + static boolean isEndLineSign(char c){ +// for (char sign: endLineSigns){ +// if (c == sign){ +// return true; +// } +// } +// +// return false; + return getCharacterType(c) == characterType.lineEnd; } //map from Arabian characters to their contextual form in the beginning of the word