olikraus / u8g2

U8glib library for monochrome displays, version 2
Other
5.19k stars 1.05k forks source link

Custom callback for u8g2_DrawStr #1754

Closed Sovichea closed 2 years ago

Sovichea commented 2 years ago

Hi There,

Currently, I'm developing a text engine to support Khmer script in u8g2. In Khmer script, the order of typing is different from the order of text to be displayed. For example,

Typed: ស + ្ + រ Display: ស្រ

For this reason, a text shaping algorithm must be implemented separately. For my case, I have the implementation of such algorithm, which can be found in my Github page. It works fine on its own until I start using mui library to create menu for my application. All functions in the library reference back to u8g2_DrawStr which call u8g2_draw_string function.

I want to know if it is possible there is any workaround that I can make to switch between the default u8g2_draw_string and u8g2_draw_string_khmer whenever necessary.

Thank you,

olikraus commented 2 years ago
  1. Using MUI

Thanks for using MUI, however it is not yet released and very unstable. In fact MUI version from 2.31 is very outdated. There will be a lot of changes.

  1. Callback for DrawStr

I personally would prefer to create a new function, which in turn calls DrawStr Additionally I could imagine to create a callback just for MUI. Would this be ok?

MUI Progress Ticket: #1747

Sovichea commented 2 years ago
  1. Yes I know that mui is not stable yet and I had to implement a lot of custom callback to suit my need. It working great in my application for now, but I also plan to update to code a long the way.

  2. I think creating a callback to custom DrawStr would be a great solution. I imagine I can set up the font and draw string callback in a single different MUI_STYLE field, which will open up the support for other languages similar to Khmer script.

olikraus commented 2 years ago

My idea was to keep font assignment and string two separate MUI commands (MUI_STYLE and MUI_LABEL for example)

https://github.com/olikraus/u8g2/blob/ef515e6c772ea9c1f6e67a993001ce11992845c6/sys/arduino/u8g2_page_buffer/MUIBlink/MUIBlink.ino#L479-L483

The MUIF definition of the corresponding style also got simplified meanwhile. From the same file: https://github.com/olikraus/u8g2/blob/ef515e6c772ea9c1f6e67a993001ce11992845c6/sys/arduino/u8g2_page_buffer/MUIBlink/MUIBlink.ino#L378-L382

This means there will a new MUIF which allows you to set the font for the corresponding style number (no need to write your own callback for the style)

Having a callback for the draw callback might allow you to change the font also, but I think it will make the form description in MUI string less flexible.

olikraus commented 2 years ago

The problem is more complicated. I would also need a callback for the u8g2_GetUTF8Width() width function. Moreover I assume you mean the DrawUTF8 function instead of DrawStr

Sovichea commented 2 years ago

This means there will a new MUIF which allows you to set the font for the corresponding style number (no need to write your own callback for the style)

Yes, you are right. I was referring to DrawUTF8 function. I think it would make sense to have something like MUIF_U8G2_FONT_STYLE_CB(0, khmer_font, draw_string_khmer), which setup the callback for DrawUTF8. Then MUIF_U8G2_FONT_STYLE(1, u8g2_font_helvR08_tr) will restore the default callback. So the above code snapshot is still valid:

MUI_STYLE(1) MUI_LABEL(5, 9, "Numeric (MUD)") MUI_STYLE(0) MUI_XY("HR", 0,12) MUI_LABEL(5,24, "ពន្លឺ")

The problem is more complicated. I would also need a callback for the u8g2_GetUTF8Width() width function.

I'm not sure I understand this part.

olikraus commented 2 years ago

u8g2_GetUTF8Width() : Some MUI functions also require the width of the resulting string.This requires not only drawing the string but also the calculation of the width of the string. If you alter the drawing then probably you will also alter the width of the string.

Do you only require the callback for MUI_LABEL? If so, then the implementation would be simple and could be done already right now.

Sovichea commented 2 years ago

u8g2_GetUTF8Width() : Some MUI functions also require the width of the resulting string.This requires not only drawing the string but also the calculation of the width of the string

I see.

Do you only require the callback for MUI_LABEL? If so, then the implementation would be simple and could be done already right now.

Actually, I have tried replacing the callback directly in DrawUTF8 and I'm able to use it with other MUI functions to generate button and input fields with Khmer text. So, I'm thinking this implementation should support all MUI functions and not just MUI_LABEL.

Here is the snapshot of the code and its result:

u8g2_uint_t u8g2_DrawUTF8(u8g2_t u8g2, u8g2_uint_t x, u8g2_uint_t y, const char str) { u8g2->u8x8.next_cb = u8x8_utf8_next; return u8g2_draw_string_khmer(u8g2, x, y, str); }

Result on GLCD

olikraus commented 2 years ago

Very nice. I added the callback topic to my list of todo's but I don't know when I will have time to work on this.

I have created beta release 2.32.8 including the latest MUI source. Please consider to use this for your menues. Manuals should be up to date (but still incomplete): https://github.com/olikraus/u8g2/wiki/muiref https://github.com/olikraus/u8g2/wiki/muimanual

MUI Example code is here: https://github.com/olikraus/u8g2/tree/master/sys/arduino/u8g2_page_buffer/MUIBlink https://github.com/olikraus/u8g2/tree/master/sys/arduino/u8g2_page_buffer/MUICountDown https://github.com/olikraus/u8g2/tree/master/sys/arduino/u8g2_page_buffer/MUIStopwatch ...

You can download the latest U8g2 beta release from here: https://github.com/olikraus/U8g2_Arduino/archive/master.zip

  1. Remove the existing U8g2_Arduino library (https://stackoverflow.com/questions/16752806/how-do-i-remove-a-library-from-the-arduino-environment)
  2. Install the U8g2_Arduino Zip file via Arduino IDE, add zip library menu (https://www.arduino.cc/en/Guide/Libraries).
Sovichea commented 2 years ago

That's great! Thank you.