Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find out locale-dependent text orientation in java?

While I am writing a format and parse engine, I would like to find out - given a j.u.Locale, if the general text orientation is right-to-left (letter chars). What I have seen is:

1.) Character#getDirectionality(char) This requires the knowledge of the concrete char to be parsed which is not always easy due to possible fill chars.

2.) java.awt.ComponentOrientation#getOrientation(Locale) This method has two problems for me. First I would not like to be dependent on awt or other gui libraries (anticipating a possible later modularization of Java). Second and more important: The implementation of this method in OpenJDK and Android just use a very simple approach, namely: If the language is one of (ar, fa, iw, ur) then the method says RIGHT_TO_LEFT. But looking at Wikipedia-ISO-639 it appears that there are more languages which have a right-to-left-orientation, for example the ISO-639-code 'he' (hebrew).

So my question now is, do you know a better approach? At the moment I tend just to use the Wikipedia list, that is, to refine the java.awt.ComponentOrientation approach with a better language list.

like image 982
Meno Hochschild Avatar asked Dec 09 '22 10:12

Meno Hochschild


2 Answers

After some further research I have found out that the language code 'iw' is just the old form for 'he'. And the expression new Locale("he").getLanguage() would provide the result "iw"!

Nevertheless the ComponentOrientation-method is obviously not up to date, since it is missing the following languages according to Wikipedia:

yi (yiddish plus old form ji), dv (maldivian), ps (pashto) and ha (hausa)

So I have refined the approach of ComponentOrientation and added these missing languages. The final code looks like this:

private static final Set<String> RTL;

static {
  Set<String> lang = new HashSet<String>();
  lang.add("ar");
  lang.add("dv");
  lang.add("fa");
  lang.add("ha");
  lang.add("he");
  lang.add("iw");
  lang.add("ji");
  lang.add("ps");
  lang.add("sd");
  lang.add("ug");
  lang.add("ur");
  lang.add("yi");
  RTL = Collections.unmodifiableSet(lang);
}

public static boolean isTextRTL(Locale locale) {
  return RTL.contains(locale.getLanguage());
}
like image 101
Meno Hochschild Avatar answered Dec 11 '22 00:12

Meno Hochschild


Based on the above, I have created:

/**
 * This static block sets up the locale's which have a right-to-left text orientation
 */
private static final Set<String> RTL;

static
{
    Set<String> lang = new HashSet<String>();

    // we go through the new Locale(), then getLanguage(), because the language codes are not always stable, according to the Locale.getLanguage() documentation
    // stripExtensions() is used so only the language and not country specific codes are used. ie: "en" rather than "en_CA"
    lang.add( new Locale( "ar" ).stripExtensions().getLanguage() ); // Arabic          //$NON-NLS-1$
    lang.add( new Locale( "dv" ).stripExtensions().getLanguage() ); // Divehi          //$NON-NLS-1$
    lang.add( new Locale( "fa" ).stripExtensions().getLanguage() ); // Persian         //$NON-NLS-1$
    lang.add( new Locale( "ha" ).stripExtensions().getLanguage() ); // Hausa           //$NON-NLS-1$
    lang.add( new Locale( "he" ).stripExtensions().getLanguage() ); // Hebrew          //$NON-NLS-1$
    lang.add( new Locale( "iw" ).stripExtensions().getLanguage() ); // Hebrew          //$NON-NLS-1$
    lang.add( new Locale( "ji" ).stripExtensions().getLanguage() ); // Yiddish         //$NON-NLS-1$
    lang.add( new Locale( "ps" ).stripExtensions().getLanguage() ); // Pushto          //$NON-NLS-1$
    lang.add( new Locale( "sd" ).stripExtensions().getLanguage() ); // Sindhi          //$NON-NLS-1$
    lang.add( new Locale( "ug" ).stripExtensions().getLanguage() ); // Uighur          //$NON-NLS-1$
    lang.add( new Locale( "ur" ).stripExtensions().getLanguage() ); // Urdu            //$NON-NLS-1$
    lang.add( new Locale( "yi" ).stripExtensions().getLanguage() ); // Yiddish         //$NON-NLS-1$

    RTL = Collections.unmodifiableSet( lang );
}

along with:

/**
 * Returns either SWT.RIGHT_TO_LEFT or SWT.LEFT_TO_RIGHT dependent on the Locale's orientation
 */
public static int getSWTOrientation( Locale locale )
{
    return RTL.contains( locale.stripExtensions().getLanguage() ) ? SWT.RIGHT_TO_LEFT : SWT.LEFT_TO_RIGHT;
}

/**
 * Returns true if the Locale has a Right To Left text orientation
 */
public static boolean isRightToLeft( Locale locale )
{
    return RTL.contains( locale.stripExtensions().getLanguage() );
}

Thanks

like image 42
Big Guy Avatar answered Dec 10 '22 23:12

Big Guy