1 /**
2  * @file lv_bidi.h
3  *
4  */
5 
6 #ifndef LV_BIDI_H
7 #define LV_BIDI_H
8 
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12 
13 /*********************
14  *      INCLUDES
15  *********************/
16 #include "../lv_conf_internal.h"
17 
18 #include <stdbool.h>
19 #include <stdint.h>
20 #include "lv_txt.h"
21 
22 /*********************
23  *      DEFINES
24  *********************/
25 /*Special non printable strong characters.
26  *They can be inserted to texts to affect the run's direction*/
27 #define LV_BIDI_LRO  "\xE2\x80\xAD" /*U+202D*/
28 #define LV_BIDI_RLO  "\xE2\x80\xAE" /*U+202E*/
29 
30 /**********************
31  *      TYPEDEFS
32  **********************/
33 enum {
34     LV_BASE_DIR_LTR      = 0x00,
35     LV_BASE_DIR_RTL      = 0x01,
36     LV_BASE_DIR_AUTO     = 0x02,
37 
38     LV_BASE_DIR_NEUTRAL  = 0x20,
39     LV_BASE_DIR_WEAK     = 0x21,
40 };
41 
42 typedef uint8_t lv_base_dir_t;
43 
44 /**********************
45  * GLOBAL PROTOTYPES
46  **********************/
47 #if LV_USE_BIDI
48 
49 /**
50  * Convert a text to get the characters in the correct visual order according to
51  * Unicode Bidirectional Algorithm
52  * @param str_in the text to process
53  * @param str_out store the result here. Has the be `strlen(str_in)` length
54  * @param base_dir `LV_BASE_DIR_LTR` or `LV_BASE_DIR_RTL`
55  */
56 void _lv_bidi_process(const char * str_in, char * str_out, lv_base_dir_t base_dir);
57 
58 /**
59  * Auto-detect the direction of a text based on the first strong character
60  * @param txt the text to process
61  * @return `LV_BASE_DIR_LTR` or `LV_BASE_DIR_RTL`
62  */
63 lv_base_dir_t _lv_bidi_detect_base_dir(const char * txt);
64 
65 /**
66  * Get the logical position of a character in a line
67  * @param str_in the input string. Can be only one line.
68  * @param bidi_txt internally the text is bidi processed which buffer can be get here.
69  * If not required anymore has to freed with `lv_mem_free()`
70  * Can be `NULL` is unused
71  * @param len length of the line in character count
72  * @param base_dir base direction of the text: `LV_BASE_DIR_LTR` or `LV_BASE_DIR_RTL`
73  * @param visual_pos the visual character position which logical position should be get
74  * @param is_rtl tell the char at `visual_pos` is RTL or LTR context
75  * @return the logical character position
76  */
77 uint16_t _lv_bidi_get_logical_pos(const char * str_in, char ** bidi_txt, uint32_t len, lv_base_dir_t base_dir,
78                                   uint32_t visual_pos, bool * is_rtl);
79 
80 /**
81  * Get the visual position of a character in a line
82  * @param str_in the input string. Can be only one line.
83  * @param bidi_txt internally the text is bidi processed which buffer can be get here.
84  * If not required anymore has to freed with `lv_mem_free()`
85  * Can be `NULL` is unused
86  * @param len length of the line in character count
87  * @param base_dir base direction of the text: `LV_BASE_DIR_LTR` or `LV_BASE_DIR_RTL`
88  * @param logical_pos the logical character position which visual position should be get
89  * @param is_rtl tell the char at `logical_pos` is RTL or LTR context
90  * @return the visual character position
91  */
92 uint16_t _lv_bidi_get_visual_pos(const char * str_in, char ** bidi_txt, uint16_t len, lv_base_dir_t base_dir,
93                                  uint32_t logical_pos, bool * is_rtl);
94 
95 /**
96  * Bidi process a paragraph of text
97  * @param str_in the string to process
98  * @param str_out store the result here
99  * @param len length of the text
100  * @param base_dir base dir of the text
101  * @param pos_conv_out an `uint16_t` array to store the related logical position of the character.
102  * Can be `NULL` is unused
103  * @param pos_conv_len length of `pos_conv_out` in element count
104  */
105 void _lv_bidi_process_paragraph(const char * str_in, char * str_out, uint32_t len, lv_base_dir_t base_dir,
106                                 uint16_t * pos_conv_out, uint16_t pos_conv_len);
107 
108 /**
109  * Get the real text alignment from the a text alignment, base direction and a text.
110  * @param align     LV_TEXT_ALIGN_..., write back the calculated align here (LV_TEXT_ALIGN_LEFT/RIGHT/CENTER)
111  * @param base_dir  LV_BASE_DIR_..., write the calculated base dir here (LV_BASE_DIR_LTR/RTL)
112  * @param txt       a text, used with LV_BASE_DIR_AUTO to determine the base direction
113  */
114 void lv_bidi_calculate_align(lv_text_align_t * align, lv_base_dir_t * base_dir, const char * txt);
115 
116 /**********************
117  *      MACROS
118  **********************/
119 
120 #else /*LV_USE_BIDI*/
121 /**
122  * For compatibility if LV_USE_BIDI = 0
123  * Get the real text alignment from the a text alignment, base direction and a text.
124  * @param align     For LV_TEXT_ALIGN_AUTO give LV_TEXT_ALIGN_LEFT else leave unchanged, write back the calculated align here
125  * @param base_dir  Unused
126  * @param txt       Unused
127  */
lv_bidi_calculate_align(lv_text_align_t * align,lv_base_dir_t * base_dir,const char * txt)128 static inline void lv_bidi_calculate_align(lv_text_align_t * align, lv_base_dir_t * base_dir, const char * txt)
129 {
130     LV_UNUSED(txt);
131     LV_UNUSED(base_dir);
132     if(*align == LV_TEXT_ALIGN_AUTO) * align = LV_TEXT_ALIGN_LEFT;
133 }
134 #endif /*LV_USE_BIDI*/
135 
136 #ifdef __cplusplus
137 } /*extern "C"*/
138 #endif
139 
140 #endif /*LV_BIDI_H*/
141