I want to display a right to left text (which means you are supposed to read this text from right to left).
I am using Lemur and I have set a max-width so it will wrap the text.
The problem is it is displayed like below:
So I should read it from bottom to top!!
I have already set the boolean rightToLeft on BitmapText but it does not work.
As you may know some languages like Arabic, Persian,… are written from right to left. I want to be able to display them in a Label.
I will demonstrate it on WordWrapDemoState in Lemur demos.
/**
* A demo of a Label that has a maximum width set so that long strings will word
* wrap after a certain width. The label is wrapped in a popup window to
* illustrate that layouts and sizing work as expected.
*
* @author Paul Speed
*/
public class WordWrapDemoState extends BaseAppState {
/**
* A command we'll pass to the label pop-up to let us know when the user
* clicks away.
*/
private CloseCommand closeCommand = new CloseCommand();
public WordWrapDemoState() {
}
@Override
protected void initialize(Application app) {
}
@Override
protected void cleanup(Application app) {
}
@Override
protected void onEnable() {
// We'll wrap the text in a window to make sure the layout is working
Container window = new Container();
window.addChild(new Label("Word Wrapped Text", new ElementId("window.title.label")));
// An example Persian text.
// Read it from right to left.
String txt = perisantext.p("این یک متن آزمایشی می باشد");
BitmapFont font_m = getApplication().getAssetManager().loadFont("PersianFont.fnt");
Label label = window.addChild(new Label(txt));
label.setMaxWidth(200);
label.setFont(font_m);
label.setFontSize(30);
label.setTextHAlignment(HAlignment.Right);
// Add a close button to both show that the layout is working and
// also because it's better UX... even if the popup will close if
// you click outside of it.
window.addChild(new ActionButton(new CallMethodAction("Close",
window, "removeFromParent")));
// Position the window and pop it up
window.setLocalTranslation(400, 400, 100);
getState(PopupState.class).showPopup(window, closeCommand);
}
@Override
protected void onDisable() {
}
private class CloseCommand implements Command<Object> {
public void execute(Object src) {
getState(MainMenuState.class).closeChild(WordWrapDemoState.this);
}
}
}
For your ease of reading, I will represent it in English.
This is the translation of the text in English written from right to left:
String txt = ".text test a is This"; // read it from right to left
For testing purpose, I modified constructor in Label class to accept boolean rightToLeft:
public Label( String s, boolean rightToLeft ) {
this( s, true, new ElementId(ELEMENT_ID), null, rightToLeft );
}
protected Label( String s, boolean applyStyles, ElementId elementId, String style, boolean rightToLeft ) {
super(false, elementId, style);
// Set our layers
getControl(GuiControl.class).setLayerOrder(LAYER_INSETS,
LAYER_BORDER,
LAYER_BACKGROUND,
LAYER_ICON,
LAYER_SHADOW_TEXT,
LAYER_TEXT);
// Retrieve the font before creation so that if the font is
// customized by the style then we don't end up creating a
// BitmapText object just to throw it away when a new font
// is set right after. It's a limitation of BitmapText that
// can't have it's font changed post-creation.
Styles styles = GuiGlobals.getInstance().getStyles();
BitmapFont font = styles.getAttributes(elementId.getId(), style).get("font", BitmapFont.class);
this.text = new TextComponent(s, font, rightToLeft);
text.setLayer(3);
getControl(GuiControl.class).setComponent(LAYER_TEXT, text);
if( applyStyles ) {
styles.applyStyles(this, elementId, style);
}
}
note this change: this.text = new TextComponent(s, font, rightToLeft);
but setting it either to true or false has no effect. Isn’t this boolean meant to be used for the right to left LineWrapMode?
Here is the only where I found this boolean it is used:
but the problem is for reading the lines I need to have access to Letters.java and LetterQuad.java classes from com.jme3.font package but those classes are not public so can not be accessed from outside.
Hi. Im in holiday till end of month and have only my phone with me.
Anyhow you dont need to get the fonts. There is either in Textentrycomponent or Documentmodel (?) a method createcomposite (?). Follow it. This method is leading to the text that is displayed in lemur. And in one of the class you find lines (of your text) and can access them.
Im sure @pspeed may help you if you cant find it .
And yes you may modify one or more of the lemur classes e.g. by an own routine to reset the text.
Sorry for not being able to help more detailed at the moment.
@Aufricer TextEntryComponent is only for TextField. I am using a Lemur Label which uses a TextComponent and it does not expose any way to get lines.
I guess TextField uses “\n” for handling lines whereas in Label line wrapping is handled internally by BitmapText and it is declared inside LetterQuad.
Cool. I’m still interested, it just helps me focus in a direction.
If you feel extra adventurous… a simple BitmapText example might be nice to attach to the issue. (Super-adventurous would be to add it to the jme examples.)