When displaying text that is written right-to-left, this will sometimes have the behaviour of being displayed with the characters in the reverse order. This is because text is interpreted/rendered from left-to-right. This means that the simple solution is to start off by reversing the character order before rendering. E.g. if you want your right-to-left text to be displayed as ‘ABC’ then write it as ‘CBA’.
For some languages/scripts this can be done simply by adjusting the string in the translation database (or wherever these strings are stored, assuming this is for localization). But this isn’t exactly an elegant, reliable, and realistic solution. There are some libraries that we can use to solve this problem for us, let’s get started.
For the purpose of this article, the instructions are written from the Linux perspective, but the methodology is the same across Windows and Mac.
UTF8 library: https://github.com/meepen/Lua-5.1-UTF-8
BitOp library: http://bitop.luajit.org/download.html (either .tar.gz or .zip, both work)
Note
If you are on Storyboard version 5.1 and above you do not have to build the BitOp library. Instead, all you have to do is download the utf8.lua file and edit to make the following change:
local bit = bit
to
local bit = bit32
You can then continue on with what's written in the "Reversing Character Order With The UTF8 Module:" section of this article.
The BitOp library can be compiled against our Lua library and then used as a Lua module. In order to do this, we just need to point it at the libsblua.so that is included in the runtime you are using and set the include directory to be the runtime’s include/lua directory.
Extract the BitOp download and edit the Makefile
Comment out the first INCLUDES statement and replace it with:
#INCLUDES= -I/usr/local/include INCLUDES= -I/[installpath]/Crank_Storyboard/Storyboard_Engine/6.2.202003130919.36509/linux-x86_64-opengles_2.0-x11-obj/include/lua LDFLAGS= -L/[installpath]/Crank_Storyboard/Storyboard_Engine/6.2.202003130919.36509/linux-x86_64-opengles_2.0-x11-obj/lib -lsblua
Note
Make sure this is formatted for whichever specific runtime and version of Storyboard you are using. The example shown is for the Linux, opengl runtime for Storyboard v6.2
Scroll down near the bottom of the file and move SOLDFLAGS to be after the -o arguments:
Before:
$(MODSO): $(MODNAME).o $(SOCC) $(SOLDFLAGS) -o $@ $<
After:
$(MODSO): $(MODNAME).o $(SOCC) -o $@ $< $(SOLDFLAGS)
The arguments to the linker have to be placed after the -o directive otherwise it won’t bring in the sblua library.
Save this and open a terminal session in this directory.
Execute a ‘make’ command and it should build the library successfully:
Now let’s go ahead and move the newly generated bit.so into our project directory. For the purpose of this article I’ve moved it into my project’s scripts folder in a new folder titled “linux-x86_64”. This is just a nice organizational method in case you have to build for multiple platforms.
Since the library is pure Lua, it can simply be dropped right into your project’s directory. For organizational sake, I’ll put this in the /scripts directory. The UTF8 library does have a dependency on the BitOp library, however, so we will need to add the following modifications:
At the top of the file, we need to point the module to our bit.so. In this case, mine is located in [project root]/scripts/linux-x86_64/
local info = gre.env({ "target_cpu","target_os" }) local moddir = string.format("%s/%s-%s", gre.SCRIPT_ROOT, info.target_os, info.target_cpu) package.cpath = string.format("%s/?.so;%s", moddir, package.cpath)
Note
If done this way, if you have also built the BitOp lib for different platforms, it will source the correct one based on the platform, as long as you’ve labeled the folders appropriately.
Add a require for our bit lib:
Before:
local bit = bit
After:
local bit = require “bit”
And that is all the setup that is required. The next step is to actually use what we’ve included thus far.
A simple demonstration of how to use the utf8 module to reverse character order is as follows:
-- Get the arabic string, in this case it’s just hard-written, but in your case it will likely be from a database local arabic_string = 'مرحبا' local r = "" -- Iterate through each character and append them to the end of the string to flip the order for p,c in utf8.codes(arabic_string) do r = utf8.char(utf8.codepoint(c))..r end -- Set the text of the control’s text variable gre.set_value("Layer.text_ctrl.text", r)
You will also need to ensure that you set the grd_text_shaper_attrs to the appropriate value:
gre.set_value("grd_text_shaper_attrs", "script=Arabic;lang=ar")
To read more about this option and to get the appropriate ISO codes for the script and language, please refer to the documentation found here: https://support.cranksoftware.com/hc/en-us/articles/360039998812-Script-Specific-Text-Shaping-and-Layout
And that’s it, from there everything should be rendered as intended.
A sample project with these libraries compiled can be found here: LINK
A video of the process can be found here.