summaryrefslogtreecommitdiff
path: root/firmware/drivers/lcd-bitmap-common.c
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/drivers/lcd-bitmap-common.c')
-rw-r--r--firmware/drivers/lcd-bitmap-common.c97
1 files changed, 86 insertions, 11 deletions
diff --git a/firmware/drivers/lcd-bitmap-common.c b/firmware/drivers/lcd-bitmap-common.c
index 70ae00ba84..5b79879d70 100644
--- a/firmware/drivers/lcd-bitmap-common.c
+++ b/firmware/drivers/lcd-bitmap-common.c
@@ -29,6 +29,7 @@
29 ****************************************************************************/ 29 ****************************************************************************/
30#include "stdarg.h" 30#include "stdarg.h"
31#include "sprintf.h" 31#include "sprintf.h"
32#include "diacritic.h"
32 33
33#ifndef LCDFN /* Not compiling for remote - define macros for main LCD. */ 34#ifndef LCDFN /* Not compiling for remote - define macros for main LCD. */
34#define LCDFN(fn) lcd_ ## fn 35#define LCDFN(fn) lcd_ ## fn
@@ -79,15 +80,22 @@ static void lcd_gradient_rect(int x1, int x2, int y, unsigned h,
79} 80}
80#endif 81#endif
81 82
83struct lcd_bitmap_char
84{
85 bool is_rtl;
86 bool is_diacritic;
87 int width;
88 int base_width;
89};
90
82/* put a string at a given pixel position, skipping first ofs pixel columns */ 91/* put a string at a given pixel position, skipping first ofs pixel columns */
83static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str) 92static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str)
84{ 93{
85 unsigned short ch;
86 unsigned short *ucs; 94 unsigned short *ucs;
87 struct font* pf = font_get(current_vp->font); 95 struct font* pf = font_get(current_vp->font);
88 int vp_flags = current_vp->flags; 96 int vp_flags = current_vp->flags;
89 97 int i, len;
90 ucs = bidi_l2v(str, 1); 98 static struct lcd_bitmap_char chars[SCROLL_LINE_SIZE];
91 99
92 if ((vp_flags & VP_FLAG_ALIGNMENT_MASK) != 0) 100 if ((vp_flags & VP_FLAG_ALIGNMENT_MASK) != 0)
93 { 101 {
@@ -109,13 +117,59 @@ static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str)
109 } 117 }
110 } 118 }
111 119
112 while ((ch = *ucs++) != 0 && x < current_vp->width) 120 ucs = bidi_l2v(str, 1);
121 /* Mark diacritic and rtl flags for each character */
122 for (i = 0; i < SCROLL_LINE_SIZE && ucs[i]; i++)
123 chars[i].is_diacritic = is_diacritic(ucs[i], &chars[i].is_rtl);
124 len = i;
125
126 /* Get proportional width and glyph bits */
127 for (i = 0; i < len; i++)
128 chars[i].width = font_get_width(pf, ucs[i]);
129
130 /* Calculate base width for each character */
131 for (i = 0; i < len; i++)
132 {
133 if (chars[i].is_rtl)
134 {
135 /* Forward-seek the next non-diacritic character for base width */
136 if (chars[i].is_diacritic)
137 {
138 int j;
139
140 /* Jump to next non-diacritic character, and calc its width */
141 for (j = i; j < len && chars[j].is_diacritic; j++);
142
143 /* Set all related diacritic char's base-width accordingly */
144 for (; i <= j; i++)
145 chars[i].base_width = chars[j].width;
146 }
147 else
148 {
149 chars[i].base_width = chars[i].width;
150 }
151 }
152 else
153 {
154 static int last_non_diacritic_width = 0;
155
156 if (!chars[i].is_diacritic)
157 last_non_diacritic_width = chars[i].width;
158
159 chars[i].base_width = last_non_diacritic_width;
160 }
161 }
162
163 for (i = 0; i < len; i++)
113 { 164 {
114 int width;
115 const unsigned char *bits; 165 const unsigned char *bits;
166 unsigned short ch = ucs[i];
167 int width = chars[i].width;
168 int drawmode = 0, base_ofs = 0;
169 bool next_is_diacritic;
116 170
117 /* get proportional width and glyph bits */ 171 if (x >= current_vp->width)
118 width = font_get_width(pf, ch); 172 break;
119 173
120 if (ofs > width) 174 if (ofs > width)
121 { 175 {
@@ -123,13 +177,34 @@ static void LCDFN(putsxyofs)(int x, int y, int ofs, const unsigned char *str)
123 continue; 177 continue;
124 } 178 }
125 179
180 if (chars[i].is_diacritic)
181 {
182 drawmode = current_vp->drawmode;
183 current_vp->drawmode = DRMODE_FG;
184
185 base_ofs = (chars[i].base_width - width) / 2;
186 }
187
126 bits = font_get_bits(pf, ch); 188 bits = font_get_bits(pf, ch);
189 LCDFN(mono_bitmap_part)(bits, ofs, 0, width,
190 x + base_ofs, y, width - ofs, pf->height);
191
192 if (chars[i].is_diacritic)
193 {
194 current_vp->drawmode = drawmode;
195 }
127 196
128 LCDFN(mono_bitmap_part)(bits, ofs, 0, width, x, y, width - ofs, 197 /* Increment if next char is not diacritic (non-rtl),
129 pf->height); 198 * or current char is non-diacritic and next char is diacritic (rtl)*/
199 next_is_diacritic = (ucs[i + 1] && chars[i + 1].is_diacritic);
130 200
131 x += width - ofs; 201 if (ucs[i + 1] &&
132 ofs = 0; 202 ((chars[i].is_rtl && !chars[i].is_diacritic) ||
203 (!chars[i].is_rtl && (chars[i + 1].is_rtl || !chars[i + 1].is_diacritic))))
204 {
205 x += chars[i].base_width - ofs;
206 ofs = 0;
207 }
133 } 208 }
134} 209}
135/* put a string at a given pixel position */ 210/* put a string at a given pixel position */