Browse Source

constrain and scroll rendered text

Thomas Buck 11 months ago
parent
commit
3162df3c2d
4 changed files with 57 additions and 28 deletions
  1. 7
    2
      include/text.h
  2. 6
    0
      src/lcd.c
  3. 5
    1
      src/menu.c
  4. 39
    25
      src/text.c

+ 7
- 2
include/text.h View File

34
     const char *text;
34
     const char *text;
35
     int x;
35
     int x;
36
     int y;
36
     int y;
37
+    int y_text_off;
37
     bool justify;
38
     bool justify;
38
     enum mf_align_t alignment;
39
     enum mf_align_t alignment;
39
     int width;
40
     int width;
46
 };
47
 };
47
 
48
 
48
 void text_prepare_font(struct text_font *tf);
49
 void text_prepare_font(struct text_font *tf);
49
-void text_draw(struct text_conf *tc);
50
+int16_t text_draw(struct text_conf *tc);
50
 
51
 
51
-void text_box(const char *s, bool centered);
52
+int16_t text_box(const char *s, bool centered,
53
+                 const char *fontname,
54
+                 uint16_t x_off, uint16_t width,
55
+                 uint16_t y_off, uint16_t height,
56
+                 int16_t y_text_off);
52
 
57
 
53
 #endif // __TEXT_H__
58
 #endif // __TEXT_H__

+ 6
- 0
src/lcd.c View File

279
     if (bottom >= ST7789_PICO_COLUMN) {
279
     if (bottom >= ST7789_PICO_COLUMN) {
280
         bottom = ST7789_PICO_COLUMN - 1;
280
         bottom = ST7789_PICO_COLUMN - 1;
281
     }
281
     }
282
+    if (top >= bottom) {
283
+        return;
284
+    }
285
+    if (left >= right) {
286
+        return;
287
+    }
282
     //                 handle,       left,         top,      right,    bottom, color);
288
     //                 handle,       left,         top,      right,    bottom, color);
283
     st7789_fill_rect(&gs_handle, 240 - bottom - 1, left, 240 - top - 1, right, color);
289
     st7789_fill_rect(&gs_handle, 240 - bottom - 1, left, 240 - top - 1, right, color);
284
 }
290
 }

+ 5
- 1
src/menu.c View File

137
 
137
 
138
     if (strncmp(menu.buff, prev_buff, MENU_MAX_LEN) != 0) {
138
     if (strncmp(menu.buff, prev_buff, MENU_MAX_LEN) != 0) {
139
         strncpy(prev_buff, menu.buff, MENU_MAX_LEN);
139
         strncpy(prev_buff, menu.buff, MENU_MAX_LEN);
140
-        text_box(menu.buff, centered);
140
+        text_box(menu.buff, centered,
141
+                 "fixed_10x20",
142
+                 0, LCD_WIDTH,
143
+                 50, (MENU_MAX_LINES * 20) + ((MENU_MAX_LINES - 1) * 2),
144
+                 0);
141
     }
145
     }
142
 }
146
 }

+ 39
- 25
src/text.c View File

16
  * See <http://www.gnu.org/licenses/>.
16
  * See <http://www.gnu.org/licenses/>.
17
  */
17
  */
18
 
18
 
19
+#include <string.h>
20
+
19
 #include "config.h"
21
 #include "config.h"
20
 #include "log.h"
22
 #include "log.h"
21
 #include "lcd.h"
23
 #include "lcd.h"
25
 typedef struct {
27
 typedef struct {
26
     struct text_conf *options;
28
     struct text_conf *options;
27
     uint16_t anchor;
29
     uint16_t anchor;
30
+    int y;
28
 } state_t;
31
 } state_t;
29
 
32
 
30
 static uint32_t blend(uint32_t fg_c, uint32_t bg_c, uint8_t alpha) {
33
 static uint32_t blend(uint32_t fg_c, uint32_t bg_c, uint8_t alpha) {
51
                            void *state) {
54
                            void *state) {
52
     state_t *s = (state_t*)state;
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
         || (x < 0) || ((x + count) >= (s->options->x + s->options->width))) {
60
         || (x < 0) || ((x + count) >= (s->options->x + s->options->width))) {
56
         return;
61
         return;
57
     }
62
     }
73
 static bool line_callback(const char *line, uint16_t count, void *state) {
78
 static bool line_callback(const char *line, uint16_t count, void *state) {
74
     state_t *s = (state_t*)state;
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
     if (s->options->bg != TEXT_BG_NONE) {
86
     if (s->options->bg != TEXT_BG_NONE) {
77
         int16_t width = mf_get_string_width(s->options->font->font, line, count, false) + 2 * s->options->margin;
87
         int16_t width = mf_get_string_width(s->options->font->font, line, count, false) + 2 * s->options->margin;
78
         int16_t line_height = s->options->font->font->line_height;
88
         int16_t line_height = s->options->font->font->line_height;
79
 
89
 
80
         if (s->options->alignment == MF_ALIGN_LEFT) {
90
         if (s->options->alignment == MF_ALIGN_LEFT) {
81
             lcd_write_rect(s->options->x,
91
             lcd_write_rect(s->options->x,
82
-                           s->options->y,
92
+                           MAX(s->y, s->options->y),
83
                            s->options->x + width,
93
                            s->options->x + width,
84
-                           s->options->y + line_height,
94
+                           MIN(s->y + line_height, s->options->y + s->options->height),
85
                            s->options->bg);
95
                            s->options->bg);
86
         } else if (s->options->alignment == MF_ALIGN_CENTER) {
96
         } else if (s->options->alignment == MF_ALIGN_CENTER) {
87
             lcd_write_rect(s->options->x + s->options->width / 2 - width / 2,
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
                            s->options->x + s->options->width / 2 + width / 2,
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
                            s->options->bg);
101
                            s->options->bg);
92
         } else if (s->options->alignment == MF_ALIGN_RIGHT) {
102
         } else if (s->options->alignment == MF_ALIGN_RIGHT) {
93
             lcd_write_rect(s->options->x + s->options->width - width,
103
             lcd_write_rect(s->options->x + s->options->width - width,
94
-                           s->options->y,
104
+                           MAX(s->y, s->options->y),
95
                            s->options->x + s->options->width,
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
                            s->options->bg);
107
                            s->options->bg);
98
         }
108
         }
99
     }
109
     }
100
 
110
 
101
     if (s->options->justify) {
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
                             s->options->width - s->options->margin * 2,
113
                             s->options->width - s->options->margin * 2,
104
                             line, count, character_callback, state);
114
                             line, count, character_callback, state);
105
     } else {
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
                           s->options->alignment, line, count,
117
                           s->options->alignment, line, count,
108
                           character_callback, state);
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
 void text_prepare_font(struct text_font *tf) {
126
 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
     if ((!tc) || (!tc->font) || (!tc->font->font)) {
151
     if ((!tc) || (!tc->font) || (!tc->font->font)) {
141
         debug("invalid param");
152
         debug("invalid param");
142
-        return;
153
+        return 0;
143
     }
154
     }
144
 
155
 
145
     state_t state;
156
     state_t state;
146
     state.options = tc;
157
     state.options = tc;
158
+    state.y = tc->y + tc->y_text_off;
147
 
159
 
148
     if (tc->alignment == MF_ALIGN_LEFT) {
160
     if (tc->alignment == MF_ALIGN_LEFT) {
149
         state.anchor = tc->margin;
161
         state.anchor = tc->margin;
155
 
167
 
156
     mf_wordwrap(tc->font->font, tc->width - 2 * tc->margin,
168
     mf_wordwrap(tc->font->font, tc->width - 2 * tc->margin,
157
                 tc->text, line_callback, &state);
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
     static struct text_font font = {
179
     static struct text_font font = {
162
-        .fontname = "fixed_10x20",
180
+        .fontname = "",
163
         .font = NULL,
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
         text_prepare_font(&font);
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
     struct text_conf text = {
189
     struct text_conf text = {
176
-        .text = "",
190
+        .text = s,
177
         .x = x_off,
191
         .x = x_off,
178
         .y = y_off,
192
         .y = y_off,
193
+        .y_text_off = y_text_off,
179
         .justify = false,
194
         .justify = false,
180
         .alignment = centered ? MF_ALIGN_CENTER : MF_ALIGN_LEFT,
195
         .alignment = centered ? MF_ALIGN_CENTER : MF_ALIGN_LEFT,
181
         .width = width,
196
         .width = width,
191
                    y_off + height - 1,
206
                    y_off + height - 1,
192
                    RGB_565(0x00, 0x00, 0x00));
207
                    RGB_565(0x00, 0x00, 0x00));
193
 
208
 
194
-    text.text = s;
195
-    text_draw(&text);
209
+    return text_draw(&text);
196
 }
210
 }

Loading…
Cancel
Save