|
@@ -16,6 +16,8 @@
|
16
|
16
|
* See <http://www.gnu.org/licenses/>.
|
17
|
17
|
*/
|
18
|
18
|
|
|
19
|
+#include <string.h>
|
|
20
|
+
|
19
|
21
|
#include "config.h"
|
20
|
22
|
#include "log.h"
|
21
|
23
|
#include "lcd.h"
|
|
@@ -25,6 +27,7 @@
|
25
|
27
|
typedef struct {
|
26
|
28
|
struct text_conf *options;
|
27
|
29
|
uint16_t anchor;
|
|
30
|
+ int y;
|
28
|
31
|
} state_t;
|
29
|
32
|
|
30
|
33
|
static uint32_t blend(uint32_t fg_c, uint32_t bg_c, uint8_t alpha) {
|
|
@@ -51,7 +54,9 @@ static void pixel_callback(int16_t x, int16_t y, uint8_t count, uint8_t alpha,
|
51
|
54
|
void *state) {
|
52
|
55
|
state_t *s = (state_t*)state;
|
53
|
56
|
|
54
|
|
- if ((y < 0) || (y >= (s->options->y + s->options->height))
|
|
57
|
+ if ((y < 0) || (y >= (s->options->y + s->options->height)
|
|
58
|
+ || (y < s->options->y)
|
|
59
|
+ || (y >= LCD_HEIGHT)) || (x >= LCD_WIDTH)
|
55
|
60
|
|| (x < 0) || ((x + count) >= (s->options->x + s->options->width))) {
|
56
|
61
|
return;
|
57
|
62
|
}
|
|
@@ -73,43 +78,49 @@ static uint8_t character_callback(int16_t x, int16_t y, mf_char character,
|
73
|
78
|
static bool line_callback(const char *line, uint16_t count, void *state) {
|
74
|
79
|
state_t *s = (state_t*)state;
|
75
|
80
|
|
|
81
|
+ if (s->y < (s->options->y - s->options->font->font->line_height)) {
|
|
82
|
+ s->y += s->options->font->font->line_height;
|
|
83
|
+ return true;
|
|
84
|
+ }
|
|
85
|
+
|
76
|
86
|
if (s->options->bg != TEXT_BG_NONE) {
|
77
|
87
|
int16_t width = mf_get_string_width(s->options->font->font, line, count, false) + 2 * s->options->margin;
|
78
|
88
|
int16_t line_height = s->options->font->font->line_height;
|
79
|
89
|
|
80
|
90
|
if (s->options->alignment == MF_ALIGN_LEFT) {
|
81
|
91
|
lcd_write_rect(s->options->x,
|
82
|
|
- s->options->y,
|
|
92
|
+ MAX(s->y, s->options->y),
|
83
|
93
|
s->options->x + width,
|
84
|
|
- s->options->y + line_height,
|
|
94
|
+ MIN(s->y + line_height, s->options->y + s->options->height),
|
85
|
95
|
s->options->bg);
|
86
|
96
|
} else if (s->options->alignment == MF_ALIGN_CENTER) {
|
87
|
97
|
lcd_write_rect(s->options->x + s->options->width / 2 - width / 2,
|
88
|
|
- s->options->y,
|
|
98
|
+ MAX(s->y, s->options->y),
|
89
|
99
|
s->options->x + s->options->width / 2 + width / 2,
|
90
|
|
- s->options->y + line_height,
|
|
100
|
+ MIN(s->y + line_height, s->options->y + s->options->height),
|
91
|
101
|
s->options->bg);
|
92
|
102
|
} else if (s->options->alignment == MF_ALIGN_RIGHT) {
|
93
|
103
|
lcd_write_rect(s->options->x + s->options->width - width,
|
94
|
|
- s->options->y,
|
|
104
|
+ MAX(s->y, s->options->y),
|
95
|
105
|
s->options->x + s->options->width,
|
96
|
|
- s->options->y + line_height,
|
|
106
|
+ MIN(s->y + line_height, s->options->y + s->options->height),
|
97
|
107
|
s->options->bg);
|
98
|
108
|
}
|
99
|
109
|
}
|
100
|
110
|
|
101
|
111
|
if (s->options->justify) {
|
102
|
|
- mf_render_justified(s->options->font->font, s->anchor + s->options->x, s->options->y,
|
|
112
|
+ mf_render_justified(s->options->font->font, s->anchor + s->options->x, s->y,
|
103
|
113
|
s->options->width - s->options->margin * 2,
|
104
|
114
|
line, count, character_callback, state);
|
105
|
115
|
} else {
|
106
|
|
- mf_render_aligned(s->options->font->font, s->anchor + s->options->x, s->options->y,
|
|
116
|
+ mf_render_aligned(s->options->font->font, s->anchor + s->options->x, s->y,
|
107
|
117
|
s->options->alignment, line, count,
|
108
|
118
|
character_callback, state);
|
109
|
119
|
}
|
110
|
120
|
|
111
|
|
- s->options->y += s->options->font->font->line_height;
|
112
|
|
- return true;
|
|
121
|
+ s->y += s->options->font->font->line_height;
|
|
122
|
+ return (s->y < (s->options->y + s->options->height))
|
|
123
|
+ && (s->y < LCD_HEIGHT);
|
113
|
124
|
}
|
114
|
125
|
|
115
|
126
|
void text_prepare_font(struct text_font *tf) {
|
|
@@ -136,14 +147,15 @@ void text_prepare_font(struct text_font *tf) {
|
136
|
147
|
//}
|
137
|
148
|
}
|
138
|
149
|
|
139
|
|
-void text_draw(struct text_conf *tc) {
|
|
150
|
+int16_t text_draw(struct text_conf *tc) {
|
140
|
151
|
if ((!tc) || (!tc->font) || (!tc->font->font)) {
|
141
|
152
|
debug("invalid param");
|
142
|
|
- return;
|
|
153
|
+ return 0;
|
143
|
154
|
}
|
144
|
155
|
|
145
|
156
|
state_t state;
|
146
|
157
|
state.options = tc;
|
|
158
|
+ state.y = tc->y + tc->y_text_off;
|
147
|
159
|
|
148
|
160
|
if (tc->alignment == MF_ALIGN_LEFT) {
|
149
|
161
|
state.anchor = tc->margin;
|
|
@@ -155,27 +167,30 @@ void text_draw(struct text_conf *tc) {
|
155
|
167
|
|
156
|
168
|
mf_wordwrap(tc->font->font, tc->width - 2 * tc->margin,
|
157
|
169
|
tc->text, line_callback, &state);
|
|
170
|
+
|
|
171
|
+ return state.y;
|
158
|
172
|
}
|
159
|
173
|
|
160
|
|
-void text_box(const char *s, bool centered) {
|
|
174
|
+int16_t text_box(const char *s, bool centered,
|
|
175
|
+ const char *fontname,
|
|
176
|
+ uint16_t x_off, uint16_t width,
|
|
177
|
+ uint16_t y_off, uint16_t height,
|
|
178
|
+ int16_t y_text_off) {
|
161
|
179
|
static struct text_font font = {
|
162
|
|
- .fontname = "fixed_10x20",
|
|
180
|
+ .fontname = "",
|
163
|
181
|
.font = NULL,
|
164
|
182
|
};
|
165
|
|
- if (font.font == NULL) {
|
|
183
|
+
|
|
184
|
+ if ((font.font == NULL) || (strcmp(font.fontname, fontname) != 0)) {
|
|
185
|
+ font.fontname = fontname;
|
166
|
186
|
text_prepare_font(&font);
|
167
|
187
|
}
|
168
|
188
|
|
169
|
|
- int x_off = 0;
|
170
|
|
- int width = LCD_WIDTH;
|
171
|
|
-
|
172
|
|
- int y_off = 50;
|
173
|
|
- int height = (MENU_MAX_LINES * 20) + ((MENU_MAX_LINES - 1) * 2);
|
174
|
|
-
|
175
|
189
|
struct text_conf text = {
|
176
|
|
- .text = "",
|
|
190
|
+ .text = s,
|
177
|
191
|
.x = x_off,
|
178
|
192
|
.y = y_off,
|
|
193
|
+ .y_text_off = y_text_off,
|
179
|
194
|
.justify = false,
|
180
|
195
|
.alignment = centered ? MF_ALIGN_CENTER : MF_ALIGN_LEFT,
|
181
|
196
|
.width = width,
|
|
@@ -191,6 +206,5 @@ void text_box(const char *s, bool centered) {
|
191
|
206
|
y_off + height - 1,
|
192
|
207
|
RGB_565(0x00, 0x00, 0x00));
|
193
|
208
|
|
194
|
|
- text.text = s;
|
195
|
|
- text_draw(&text);
|
|
209
|
+ return text_draw(&text);
|
196
|
210
|
}
|