summaryrefslogtreecommitdiff
path: root/src/user/raleigh/s
diff options
context:
space:
mode:
Diffstat (limited to 'src/user/raleigh/s')
-rw-r--r--src/user/raleigh/s/text_flower.cpp96
1 files changed, 96 insertions, 0 deletions
diff --git a/src/user/raleigh/s/text_flower.cpp b/src/user/raleigh/s/text_flower.cpp
new file mode 100644
index 0000000..bd4ecd8
--- /dev/null
+++ b/src/user/raleigh/s/text_flower.cpp
@@ -0,0 +1,96 @@
+#include <raleigh/s/text_flower.h>
+#include <knob/block.h>
+
+namespace raleigh {
+ text_flower::text_flower(const char *s, uint32_t cols, uint32_t max_rows)
+ : s(s), lines(max_rows ? max_rows : 10), offsets(max_rows ? max_rows : 10),
+ max_rows(max_rows), cols(cols) {
+ flow_text();
+ }
+
+ __attribute__ ((pure))
+ uint32_t text_flower::get_n_lines() {
+ return lines.n_entries;
+ }
+
+ __attribute__ ((pure))
+ char *text_flower::get_nth_line(uint32_t n) {
+ return lines.buf[n];
+ }
+
+ __attribute__ ((pure))
+ uint32_t text_flower::get_line_offset(uint32_t n) {
+ return offsets.buf[n];
+ }
+
+ void text_flower::draw_text(_pixel_t *start, uint32_t pitch, const struct font_info *fi, _pixel_t color) {
+ for (uint32_t y = 0; y < lines.n_entries; ++y) {
+ const char *line = lines.buf[y];
+ for (uint32_t x = 0; line[x]; ++x)
+ put_char_no_bg(fi, line[x], start + y * fi->space_height * pitch + x * fi->space_width, pitch, color);
+ }
+ }
+
+ void text_flower::push_line() {
+ lines.add_back(strndup(line_start, row_len));
+ offsets.add_back(line_start - s);
+ line_start = on_char;
+ row_len = 0;
+ if (max_rows && (lines.n_entries == max_rows))
+ on_char = "";
+ }
+
+ void text_flower::flow_text() {
+ for (uint32_t i = 0; i < lines.n_entries; ++i)
+ free_block(lines.buf[i]);
+
+ lines.n_entries = 0;
+ offsets.n_entries = 0;
+ line_start = on_char = s;
+ row_len = 0;
+
+ while (*on_char) {
+ if (*on_char == '\n') {
+ ++on_char;
+ push_line();
+ }
+
+ else if (*on_char == ' ') {
+ ++on_char;
+ if (row_len != 0) {
+ if (++row_len == cols)
+ push_line();
+ }
+ else
+ ++line_start;
+ }
+
+ else {
+ uint32_t word_len = str_find_any(on_char, " \n");
+ if (!cols) {
+ row_len += word_len;
+ on_char += word_len;
+ }
+
+ else if (row_len + word_len <= cols) {
+ row_len += word_len;
+ on_char += word_len;
+ if (row_len == cols)
+ push_line();
+ }
+
+ else if (word_len > cols) {
+ on_char += cols - row_len;
+ row_len = cols;
+ push_line();
+ }
+
+ else
+ push_line();
+ }
+ }
+
+ if (row_len && (!max_rows || (lines.n_entries != max_rows)))
+ push_line();
+ }
+} \ No newline at end of file