Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RTL fixes #595

Merged
merged 18 commits into from
May 6, 2024
32 changes: 30 additions & 2 deletions app/src/main/java/org/thunderdog/challegram/U.java
Original file line number Diff line number Diff line change
Expand Up @@ -2149,7 +2149,7 @@ public static float measureText (char[] in, int start, int end, @NonNull Paint p
return 0;
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (Config.USE_TEXT_ADVANCE && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Strings.requiresBidi(in, start, end)) {
/*
getTextRunAdvances(char[] chars, int index, int count,
int contextIndex, int contextCount, boolean isRtl, float[] advances,
Expand Down Expand Up @@ -2278,6 +2278,34 @@ private static float getRunAdvance (@NonNull CharSequence in, int start, int end
}
}*/

public static float measureTextRun (@Nullable CharSequence in, @NonNull Paint p, boolean isRtl) {
final int count;
if (in == null || (count = in.length()) == 0) {
return 0;
}

if (Config.USE_TEXT_ADVANCE && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return p.getRunAdvance(in, 0, count, 0, in.length(), isRtl, count);
}

return measureText(in, p);
}

public static float measureTextRun (@Nullable CharSequence in, int start, int end, @NonNull Paint p, boolean isRtl) {
final int count = end - start;

if (in == null || in.length() == 0 || count <= 0) {
return 0;
}

if (Config.USE_TEXT_ADVANCE && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
return p.getRunAdvance(in, start, end, 0, in.length(), isRtl, end);
}

return measureText(in, start, end, p);
}

@Deprecated
public static float measureText (@Nullable CharSequence in, int start, int end, @NonNull Paint p) {
final int count = end - start;

Expand All @@ -2288,7 +2316,7 @@ public static float measureText (@Nullable CharSequence in, int start, int end,
if (p == null)
throw new IllegalArgumentException();

if (Config.USE_TEXT_ADVANCE && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && Strings.getTextDirection(in, start, end) != Strings.DIRECTION_RTL) {
if (Config.USE_TEXT_ADVANCE && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !Strings.requiresBidi(in, start, end)) {
return p.getRunAdvance(in, start, end, 0, in.length(), false, end);
} else {
float[] widths = pickWidths(count, true);
Expand Down
65 changes: 65 additions & 0 deletions app/src/main/java/org/thunderdog/challegram/tool/Strings.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,71 @@ public static boolean hostsEqual (String url1, String url2) {
return false;
}

public static boolean requiresBidi (CharSequence text, int start, int end) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
// Source: android.icu.text.Bidi.requiresBidi
// but uses CharSequence instead of char[]

final int RTLMask = (1 << android.icu.lang.UCharacter.DIRECTIONALITY_RIGHT_TO_LEFT |
1 << android.icu.lang.UCharacter.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC |
1 << android.icu.lang.UCharacter.DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING |
1 << android.icu.lang.UCharacter.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE |
1 << android.icu.lang.UCharacter.DIRECTIONALITY_ARABIC_NUMBER);

for (int i = start; i < end; ++i) {
if (((1 << android.icu.lang.UCharacter.getDirection(text.charAt(i))) & RTLMask) != 0) {
return true;
}
}
return false;
} else { // todo: test difference between UCharacter and Character
final int RTLMask = (1 << Character.DIRECTIONALITY_RIGHT_TO_LEFT |
1 << Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC |
1 << Character.DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING |
1 << Character.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE |
1 << Character.DIRECTIONALITY_ARABIC_NUMBER);

for (int i = start; i < end; ++i) {
if (((1 << Character.getDirectionality(text.charAt(i))) & RTLMask) != 0) {
return true;
}
}
return false;
}
}

public static boolean requiresBidi (char[] text, int start, int end) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
// Source: android.icu.text.Bidi.requiresBidi

final int RTLMask = (1 << android.icu.lang.UCharacter.DIRECTIONALITY_RIGHT_TO_LEFT |
1 << android.icu.lang.UCharacter.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC |
1 << android.icu.lang.UCharacter.DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING |
1 << android.icu.lang.UCharacter.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE |
1 << android.icu.lang.UCharacter.DIRECTIONALITY_ARABIC_NUMBER);

for (int i = start; i < end; ++i) {
if (((1 << android.icu.lang.UCharacter.getDirection(text[i])) & RTLMask) != 0) {
return true;
}
}
return false;
} else {
final int RTLMask = (1 << Character.DIRECTIONALITY_RIGHT_TO_LEFT |
1 << Character.DIRECTIONALITY_RIGHT_TO_LEFT_ARABIC |
1 << Character.DIRECTIONALITY_RIGHT_TO_LEFT_EMBEDDING |
1 << Character.DIRECTIONALITY_RIGHT_TO_LEFT_OVERRIDE |
1 << Character.DIRECTIONALITY_ARABIC_NUMBER);

for (int i = start; i < end; ++i) {
if (((1 << Character.getDirectionality(text[i])) & RTLMask) != 0) {
return true;
}
}
return false;
}
}

public interface CharacterCounter {
boolean accept (char c);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@
import org.thunderdog.challegram.util.SenderPickerDelegate;
import org.thunderdog.challegram.util.StringList;
import org.thunderdog.challegram.util.Unlockable;
import org.thunderdog.challegram.util.text.Text;
import org.thunderdog.challegram.util.text.TextColorSets;
import org.thunderdog.challegram.v.HeaderEditText;
import org.thunderdog.challegram.v.MessagesLayoutManager;
Expand Down Expand Up @@ -400,6 +401,7 @@ public List<HapticMenuHelper.MenuItem> onCreateHapticMenu (View view) {
}
if (BuildConfig.DEBUG) {
items.add(new HapticMenuHelper.MenuItem(R.id.btn_sendToast, "Show toast", R.drawable.baseline_warning_24));
items.add(new HapticMenuHelper.MenuItem(R.id.btn_debugLtrEmoji, "Send LTR emoji", R.drawable.baseline_warning_24));
}
if (canSelectSender()) {
items.add(0, createHapticSenderItem(R.id.btn_openSendersMenu, chat.messageSenderId, false, false));
Expand Down Expand Up @@ -453,6 +455,8 @@ public boolean onHapticMenuItemClick (View view, View parentView, HapticMenuHelp
send(modifiedSendOptions, true);
}
});
} else if (viewId == R.id.btn_debugLtrEmoji) {
pickDateOrProceed(Td.newSendOptions(), (sendOptions, disableMarkdown) -> send(new TdApi.InputMessageText(new TdApi.FormattedText(Text.bidiGenerateTestMessage(), new TdApi.TextEntity[0]), null, false), false, sendOptions, null));
}
return true;
}
Expand Down