clay icon indicating copy to clipboard operation
clay copied to clipboard

Right to left layout

Open mattahj opened this issue 1 month ago • 2 comments

I had a go at implementing right to left layout and it was surprisingly quick to get something working just from poking around with the nextChildOffset and a few other tweaks. If this approach is not good I would love some pointers about what to do instead.

Screenshot 2025-11-29 at 18 16 44

I have not yet tested very much or checked any edge cases, but I thought I will throw up this draft PR to check if this change would be wanted in clay? I would love to see clay used for some AAA game UIs but I think one of the blockers for that at the moment is lack of support for right to left layout for elements and text (every game I have worked on in that space needed Arabic localisation for example). I will have a go at the right-to-left text layout as well this weekend if I get some time!

mattahj avatar Nov 29 '25 16:11 mattahj

Looking in to this a bit more I have come to a few conclusions:

  1. The text engine in use on the user/renderer side would need to support shaping and all that stuff to properly support RTL languages. SDL_TTF does with harfbuzz enabled so I'm going to try that out. I don't think clay's simple text layout needs to be modified at all, because it's the user's measure text callback which does the actual measuring? (I'm not an expert in this area by any means, so I can be totally wrong!)
  2. Just adding right to left at the layoutDirection level should be enough I think. It makes it easy to build layouts that can be switched from LTR -> RTL just by changing the layout direction (e.g. see the air bnb examples here https://www.frontendundefined.com/posts/monthly/rtl-layouts/ - that kind of switch is possible without having to add extra spacer elements or anything like that with RTL layout direction)

I'm going to try to setup a test with SDL2 + SDL_TTF + harfbuzz and see if I can replicate some sample RTL layouts.

Another localization thing I was thinking of is text breaking. Clay always assumes that we break text using spaces, but in some languages that's not the case. Would it be worth adding a new user supplied function for checking when to break text to a new line? (e.g. Clay_SetTextBreakFunction). That would kinda match how the big middlewares do it, for example Coherent Gameface expects the user to provide an implementation of this IInternationalizationManager interface which handles it:

"Optional internationalization manager used for creating text break iterators. Eastern languages like Chinese, Japanese and Thai won’t wrap properly without this implemented."

(https://docs.coherent-labs.com/cpp-gameface/api_reference/classes/structcohtml_1_1_system_settings/#variable-internationalizationmanager, https://docs.coherent-labs.com/cpp-gameface/api_reference/classes/classcohtml_1_1_i_internationalization_manager/)

mattahj avatar Nov 30 '25 11:11 mattahj

Google-translated arabic version of the demo application:

https://github.com/user-attachments/assets/d25d44c8-0e05-49ad-9ed2-8474c105cc55

Soo yeah, as long as a proper text engine is used then it seems possible to support RTL languages properly with just the addition of CLAY_RIGHT_TO_LEFT layout direction. In this case I only had to make these small changes to the demo app:

  1. Compile SDL_TTF with harfbuzz support. Honestly this was the hardest part, and I still need to figure it out properly. I ended up having to hardcode the include and link directories in CMakeLists for the SDL2 demo 😬 , but there must be a nice cmakey way to do it so it works across all platforms
  2. Modified layoutDirection and textAlignment in the app layout where needed (I also removed the spacer in the nav bar so it was easier to tell what was happening 😆 )
  3. Changed the font to NotoSans-Regular (also set it to RTL with TTF_SetFontDirection + set the font script with TTF_SetFontScriptName so that the characters join up properly)
  4. Google-translated all of the strings

In a real application I would assume the approach would be something like using some helper functions when setting text align and layout direction, which would automatically start flipping left to right when the user's code detects that an RTL locale has been selected (reading the same config as when the application changes font and etc...)

One thing to consider is if clay would ever support something like the HTML 'dir' attribute (https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Global_attributes/dir) which can change the layout direction and text direction for the element it's applied to + all of the descendants, or if this kind of locale specific layout stuff is always left to the user.

edit: I could maybe add a new example to showcase how to do RTL/localization related things rather than messing up the SDL2 example

mattahj avatar Nov 30 '25 14:11 mattahj