5

I am creating an application that should support two languages, English, and Hebrew.

The problem is that Hebrew is Right-To-Left western language and English is Left-To-Right language, and LibGDX does not support RTL fonts.

I have created the bitmap for the font and everything works

img

But when I write in hebrew, it will write the words reversed. I have a solution for this when I write solely in hebrew, just reverse the words using a StringBuilder, but that's a cheap-fix. But what if I want to implemnet a chat, or character name?

Veve
  • 6,643
  • 5
  • 39
  • 58
Artemkller545
  • 979
  • 3
  • 21
  • 55
  • It looks like [LibGDX does not support RTL languages](https://github.com/libgdx/libgdx/issues/787), not out of the box anyway. – asherbret May 24 '16 at 19:45
  • How are you using the `Bitmap` to display as a font? Or do you already have a .ttf or .otf file for the font? – AkashBhave May 24 '16 at 20:21
  • but why do you think your code is a "cheap build"? whats wrong with it? just because you build it and the api doesn't have support for it doesn't make it wrong, can you provide the code of this "cheap build"? – Omar Ayala May 26 '16 at 18:41
  • @OmarAyala Because this solution does not work when you mix a RTL and LTR langauges together, it will just mess up. If I write in English, it will write english as RTL – Artemkller545 May 26 '16 at 21:08
  • what if you use the strategy pattern to override the behaviors you want at runtime? – Omar Ayala May 27 '16 at 06:31

3 Answers3

6

From what I can see the easiest solution is to use Heiro. If you look at this thread Hiero Rendering Arabic fonts Right to Left where there is recent provision to accomodate RTL

enter image description here

From there it becomes increasingly difficult. There are quite a few questions about this issue (one example Showing non-western language from right to left in libgdx (Android)) and fewer solutions.

You have the option of creating a library of glyphs of strings for commonly used words or expression, though this is a painstaking process to set up and there is an overhead in terms of time when using chat, as there is with your string reversal.

This discussion in the libgdx github Support for complex font rendering (Chinese, Arabic, ...). goes into these and more options including work done to support Windows sridharsundaram/complexscriptlayout, which, although that is not Android, may be worth investigating for further development ideas.

On the positive side, there are an increasing number of recent developments in this front, so RTL and bidi formats should become increasingly easier for developers using libgdx.

Of interest is this support issue Right-To-Left Text Rendering Support #787 as there are breadcrumb trails of people with the same issue developing resources.

Community
  • 1
  • 1
0

As of right now, there really isn't a way to render Right to Left text, as shown by this thread about it. So the only way to really do it is to reverse the text with StringBuilder, and then display that. A more efficient way to render the reversed text is to create a method that will display the text accordingly, so you don't have to reverse it every time you try to write Right to Left text. If you create a method, you will be able to implement the RTL text into chats, names, or other graphics that require RTL fonts.

I also recommend converting your Bitmap to a .ttf file so that it is easy to use your custom font while also keeping a good quality. You can then use the FreeTypeFontGenerator to render your font nicely. If you cannot convert your Bitmap to a font you could also use your method of displaying text in the below method. A really good alternative is the Hiero library. You can select the RTL text check box.

Here is an example of a method that you could create to render the text (using the FreeTypeFontGenerator):

// Keep the generator here so that it is not created each time
FreeTypeFontGenerator generator = new FreeTypeFontGenerator(Gdx.files.internal("fontFile.ttf"));
public void renderRTL(float x, float y, int fontSize, String text) {
    batch.begin(); // Lets you draw on the screen

    // Reverses the text given
    StringBuilder builder = new StringBuilder();
    builder.append(text);
    builder.reverse();
    String outputText = builder.toString();

    // Creates the font
    FreeTypeFontGenerator.FreeTypeFontParameter parameter = new FreeTypeFontGenerator.FreeTypeFontParameter();
    parameter.size = fontSize;
    parameter.characters = "ALL HEBREW CHARACTERS"; // Put all your Hebrew characters in this String
    scoreFont = generator.generateFont(parameter);
    scoreFont.setColor(Color.BLACK);
    scoreFont.draw(batch, outputText, x, y); // Actually draws the text
    generator.dispose(); // Clears memory

    batch.end();
}

Make sure to add all of these dependencies into your build.gradle file (in the dependencies section):

compile "com.badlogicgames.gdx:gdx-freetype:$gdxVersion"
natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-armeabi"
natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-armeabi-v7a"
natives "com.badlogicgames.gdx:gdx-freetype-platform:$gdxVersion:natives-x86"

You could optionally add a color parameter (in RGBA format) to your method for more functionality. Hope it helps!

AkashBhave
  • 749
  • 4
  • 12
  • Misinformation? Excuse me if it looks like copying, but I didn't see your answer until I had posted mine and refreshed the page. Also, if his method is working (in terms of displaying RTL) all I'm doing is suggesting to make a method so he doesn't have to repeat code. – AkashBhave May 25 '16 at 10:23
0

Use this solution on github :

https://github.com/ultra-deep/libgdx-rtl-support

ultra.deep
  • 1,699
  • 1
  • 19
  • 23