How to add Arabic letters to keyboard

Description

I want to add an Arabic keyboard to my program but when I try to implement the code it shows empty buttons

What LVGL version are you using?

8

What do you want to achieve?

Arabic keyboard

What have you tried so far?

I’ve tried to set the keyboard mode to “LV_KEYBOARD_MODE_TEXT_ARABIC”,
added a map and then used “lv_keyboard_set_map” but still it shows the same result

Code to reproduce

//kb is defined as a global variable "static lv_obj_t * kb"
 lv_coord_t kb_height = LV_MATH_MIN(LV_VER_RES / 2, LV_DPI * 4 / 3);
            lv_obj_set_height(tv, LV_VER_RES - kb_height);
            kb = lv_keyboard_create(lv_scr_act(), NULL);
            lv_obj_set_height(kb, kb_height);
            lv_keyboard_set_mode(kb, LV_KEYBOARD_MODE_TEXT_ARABIC);
            lv_obj_align(kb, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0);
            lv_obj_set_event_cb(kb, kb_event_cb);

Screenshot and/or video

Which font are you using? It may not include the necessary characters.

Thank you for your response @embeddedt
I didn’t use anyone in particular, I though it would show a default font, was I wrong?

How can I add a font to a keyboard?

The default font doesn’t include many international characters to keep the size small. There is another font included but disabled by default which includes the needed Arabic characters. You can enable it in lv_conf.h. Be sure to change LV_FONT_DEFAULT as well.

Hello @embeddedt

sorry for the late response, I tried to enable the font by changing 0 to 1:

#define LV_FONT_MONTSERRAT_12_SUBPX 1
#define LV_FONT_MONTSERRAT_28_COMPRESSED 1
#define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 1
#define LV_FONT_SIMSUN_16_CJK 1

sorry but I didn’t find the default font as you mentioned, is it in lv_conf.h as well? or it’s in the widget example?

It’s slightly further down in the same file.

@embeddedt
Sorry I’m new to LVGL .

I defined it as such:
#define LV_FONT_DEFAULT &LV_FONT_DEJAVU_16_PERSIAN_HEBREW
but still it didn’t show the Arabic letters, was the way I defined it wrong?

I think that should have given you a warning/error, and/or crashed the application, as LV_FONT_DEJAVU_16_PERSIAN_HEBREW is just a config option that can only be 0 or 1.

The correct way to define it is like this, similarly to how Montserrat was selected:

#define LV_FONT_DEFAULT &lv_font_dejavu_16_persian_hebrew

@embeddedt

I defined it as you said but still it gives me empty buttons, is there something I need to adjust in my project as well or when creating the keyboard?

Keyboard function:
lv_coord_t kb_height = LV_MATH_MIN(LV_VER_RES / 2, LV_DPI * 4 / 3);
kb = lv_keyboard_create(lv_scr_act(), NULL);
lv_obj_set_height(kb, kb_height);
lv_obj_align(kb, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0);
lv_keyboard_set_cursor_manage(kb, true);
lv_obj_set_event_cb(kb, kb_event_cb);
lv_keyboard_set_textarea(kb, ta);

Check that the file with the Arabic keyboard map is saved as UTF-8. Otherwise, please send the keyboard map as well, as I am unable to test this on my side since it’s not part of LVGL.

@embeddedt

The map is in lv_keyboard.c file and I used:

lv_keyboard_set_mode(kb, LV_KEYBOARD_MODE_TEXT_ARABIC);

inside the kb_create function, even after I changed the default font to

#define LV_FONT_DEFAULT &lv_font_dejavu_16_persian_hebrew

lv_keyboard.c file map:

Second approach I tried is defining the map in kb_create function, first I defined the Arabic keyboard map:

    static const char* default_kb_map_ar[] = {
    "1#", "ض", "ص", "ث", "ق", "ف", "غ", "ع", "ه", "خ", "ح", "ج", "\n",
    "ش", "س", "ي", "ب", "ل", "ا", "ت", "ن", "م", "ك", "ط", LV_SYMBOL_BACKSPACE, "\n",
    "ذ", "ء", "ؤ", "ر", "ى", "ة", "و", "ز", "ظ", "د", "ز", "ظ", "د", "\n",
    LV_SYMBOL_CLOSE, "abc", LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_NEW_LINE, LV_SYMBOL_OK, ""
    };

after that I used the below lines when creating the keyboard:

    lv_keyboard_set_map(kb, LV_KEYBOARD_MODE_TEXT_ARABIC,default_kb_map_ar);
    lv_keyboard_set_ctrl_map(kb, LV_KEYBOARD_MODE_TEXT_ARABIC,default_kb_map_ar);

This is the whole function:


static void kb_create(void)
{

    static const char* default_kb_map_ar[] = {
    "1#", "ض", "ص", "ث", "ق", "ف", "غ", "ع", "ه", "خ", "ح", "ج", "\n",
    "ش", "س", "ي", "ب", "ل", "ا", "ت", "ن", "م", "ك", "ط", LV_SYMBOL_BACKSPACE, "\n",
    "ذ", "ء", "ؤ", "ر", "ى", "ة", "و", "ز", "ظ", "د", "ز", "ظ", "د", "\n",
    LV_SYMBOL_CLOSE, "abc", LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_NEW_LINE, LV_SYMBOL_OK, ""
    };


    lv_coord_t kb_height = LV_MATH_MIN(LV_VER_RES / 2, LV_DPI * 4 / 3);
    kb = lv_keyboard_create(lv_scr_act(), NULL);
    lv_obj_set_height(kb, kb_height);
    lv_obj_align(kb, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0);
    lv_keyboard_set_cursor_manage(kb, true);
    //lv_keyboard_set_mode(kb, LV_KEYBOARD_MODE_TEXT_ARABIC);
    lv_keyboard_set_map(kb, LV_KEYBOARD_MODE_TEXT_ARABIC,default_kb_map_ar);
    lv_keyboard_set_ctrl_map(kb, LV_KEYBOARD_MODE_TEXT_ARABIC,default_kb_map_ar);
    lv_obj_set_event_cb(kb, kb_event_cb);
    lv_keyboard_set_textarea(kb, ta);

}

I cannot reproduce this. Here are the appropriate settings on my end:

#define LV_USE_ARABIC_PERSIAN_CHARS 1

#define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 1  /*Hebrew, Arabic, PErisan letters and all their forms*/

#define LV_THEME_DEFAULT_FONT_SMALL         &lv_font_dejavu_16_persian_hebrew
#define LV_THEME_DEFAULT_FONT_NORMAL        &lv_font_dejavu_16_persian_hebrew
#define LV_THEME_DEFAULT_FONT_SUBTITLE      &lv_font_dejavu_16_persian_hebrew
#define LV_THEME_DEFAULT_FONT_TITLE         &lv_font_dejavu_16_persian_hebrew

This is the code I am using to test, very similar to yours (you don’t need to copy the map into your function):


    lv_coord_t kb_height = LV_MATH_MIN(LV_VER_RES / 2, LV_DPI * 4 / 3);

    lv_obj_t * kb = lv_keyboard_create(lv_scr_act(), NULL);

    lv_obj_set_height(kb, kb_height);

    lv_obj_align(kb, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0);

    lv_keyboard_set_cursor_manage(kb, true);

    lv_keyboard_set_mode(kb, LV_KEYBOARD_MODE_TEXT_ARABIC);

On my board I see all the keyboard characters without problems.

I tried your code in lv_demo_widgets.c but still I’m getting the same thing.

It looks like the issue is not the keyboard_create function, but in the font definition.
This is my lv_conf.h file (Font usage section) I did exactly as you mentioned but I’m not sure what I did wrong

/*==================
 *    FONT USAGE
 *===================*/

/* The built-in fonts contains the ASCII range and some Symbols with 4 bit-per-pixel.
 * The symbols are available via `LV_SYMBOL_...` defines
 * More info about fonts: https://docs.lvgl.io/v7/en/html/overview/font.html
 * To create a new font go to: https://lvgl.com/ttf-font-to-c-array
 */

/* Montserrat fonts with bpp = 4
 * https://fonts.google.com/specimen/Montserrat  */
#define LV_FONT_MONTSERRAT_8     1
#define LV_FONT_MONTSERRAT_10    1
#define LV_FONT_MONTSERRAT_12    1
#define LV_FONT_MONTSERRAT_14    1
#define LV_FONT_MONTSERRAT_16    1
#define LV_FONT_MONTSERRAT_18    1
#define LV_FONT_MONTSERRAT_20    1
#define LV_FONT_MONTSERRAT_22    1
#define LV_FONT_MONTSERRAT_24    1
#define LV_FONT_MONTSERRAT_26    1
#define LV_FONT_MONTSERRAT_28    1
#define LV_FONT_MONTSERRAT_30    1
#define LV_FONT_MONTSERRAT_32    1
#define LV_FONT_MONTSERRAT_34    1
#define LV_FONT_MONTSERRAT_36    1
#define LV_FONT_MONTSERRAT_38    1
#define LV_FONT_MONTSERRAT_40    1
#define LV_FONT_MONTSERRAT_42    1
#define LV_FONT_MONTSERRAT_44    1
#define LV_FONT_MONTSERRAT_46    1
#define LV_FONT_MONTSERRAT_48    1

 /* Demonstrate special features */
#define LV_FONT_MONTSERRAT_12_SUBPX      1
#define LV_FONT_MONTSERRAT_28_COMPRESSED 1  /*bpp = 3*/
//#define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 1  /*Hebrew, Arabic, PErisan letters and all their forms*/
#define LV_FONT_SIMSUN_16_CJK            1  /*1000 most common CJK radicals*/


//Arabic font
#define LV_USE_ARABIC_PERSIAN_CHARS 1

#define LV_FONT_DEJAVU_16_PERSIAN_HEBREW 1  /*Hebrew, Arabic, PErisan letters and all their forms*/

#define LV_THEME_DEFAULT_FONT_SMALL         &lv_font_dejavu_16_persian_hebrew
#define LV_THEME_DEFAULT_FONT_NORMAL        &lv_font_dejavu_16_persian_hebrew
#define LV_THEME_DEFAULT_FONT_SUBTITLE      &lv_font_dejavu_16_persian_hebrew
#define LV_THEME_DEFAULT_FONT_TITLE         &lv_font_dejavu_16_persian_hebrew

/*Pixel perfect monospace font
 * http://pelulamu.net/unscii/ */
#define LV_FONT_UNSCII_8     1
#define LV_FONT_UNSCII_16     0

/* Optionally declare your custom fonts here.
 * You can use these fonts as default font too
 * and they will be available globally. E.g.
 * #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) \
 *                                LV_FONT_DECLARE(my_font_2)
 */
#define LV_FONT_CUSTOM_DECLARE

 /*Always set a default font*/
#define LV_FONT_DEFAULT &lv_font_dejavu_16_persian_hebrew

/* Enable it if you have fonts with a lot of characters.
 * The limit depends on the font size, font face and bpp
 * but with > 10,000 characters if you see issues probably you need to enable it.*/
#define LV_FONT_FMT_TXT_LARGE   0

/* Enables/disables support for compressed fonts. If it's disabled, compressed
 * glyphs cannot be processed by the library and won't be rendered.
 */
#define LV_USE_FONT_COMPRESSED 1

/* Enable subpixel rendering */
#define LV_USE_FONT_SUBPX 1
#if LV_USE_FONT_SUBPX
/* Set the pixel order of the display.
 * Important only if "subpx fonts" are used.
 * With "normal" font it doesn't matter.
 */
#define LV_FONT_SUBPX_BGR    0
#endif

Can you try it on its own (without lv_demo_widgets), just to keep the difference to a minimum? The sample I provided should work independently.

Another thing to check is which LVGL version you are using. You mentioned v8 but the screenshot looks like the v7 theme. The APIs you are using are also the v7 ones.

If you are using v7, please make sure it is updated to the release/v7 branch on GitHub, as that is the only officially supported version of v7.

So sorry I though I was using version 8, but I looked on how to know which version I’m using and it’s indeed version 7 as you mentioned.
lvgl version 7

Is this is the official supported version?

I tried your function in lv_ex_get_started_1 and still I’m getting the same result.

void lv_ex_get_started_1(void)
{
    lv_obj_t* ta = lv_textarea_create(lv_scr_act(), NULL);
    lv_textarea_set_text(ta, "");
    lv_textarea_set_placeholder_text(ta, "Message");
    lv_obj_set_event_cb(ta, ta_event_cb);

}

static void ta_event_cb(lv_obj_t* ta, lv_event_t e)
{

            lv_coord_t kb_height = LV_MATH_MIN(LV_VER_RES / 2, LV_DPI * 4 / 3);

            lv_obj_t* kb = lv_keyboard_create(lv_scr_act(), NULL);

            lv_obj_set_height(kb, kb_height);

            lv_obj_align(kb, NULL, LV_ALIGN_IN_BOTTOM_MID, 0, 0);

            lv_keyboard_set_cursor_manage(kb, true);

            lv_keyboard_set_mode(kb, LV_KEYBOARD_MODE_TEXT_ARABIC);
        
        lv_keyboard_set_textarea(kb, ta);
    
}

Double-check that your lv_conf.h changes are being picked up by adding an #error test directive to the top. The font in that screenshot is still looking very much like Montserrat.

I got this error message when I write:

#error test

image

did I do it correctly?

That’s just an error from your editor/IDE; do you also get an error when compiling the actual project?

Yes, but I’m not sure if this is the expected result.
Do I need to fix the IDE error first? if yes please tell me how.

That looks like what I would expect. At this point I am not sure what the difference is, since the snippets of lv_conf.h you posted appear to be identical to mine.

@kisvegabor Do you have any ideas?