diff options
| author | david <[email protected]> | 2026-10-13 23:04:06 -0300 |
|---|---|---|
| committer | david <[email protected]> | 2026-10-13 23:04:06 -0300 |
| commit | 7aff48a428f5c9c765f71d364594a9f273d04e8a (patch) | |
| tree | ca3ea9eb7d079766fb5096794550cfcddbe2300a /src | |
| parent | f0f954d463f7ab0e0ce792527e6567611ed67bf9 (diff) | |
| download | mikusays-c-7aff48a428f5c9c765f71d364594a9f273d04e8a.tar.gz mikusays-c-7aff48a428f5c9c765f71d364594a9f273d04e8a.zip | |
split text
Diffstat (limited to 'src')
| -rw-r--r-- | src/helper.c | 2 | ||||
| -rw-r--r-- | src/main.c | 78 |
2 files changed, 69 insertions, 11 deletions
diff --git a/src/helper.c b/src/helper.c index f258d23..108e2b9 100644 --- a/src/helper.c +++ b/src/helper.c @@ -48,7 +48,7 @@ int utf8_decode(const unsigned char *bytes, unsigned long *codepoint){ } /* this turns the library's return value into a column count so 0 1 or 2 */ -static int codepoint_width(unsigned long codepoint){ +int codepoint_width(unsigned long codepoint){ int width = widechar_wcwidth(codepoint); if(width > 0) return width; @@ -1,7 +1,5 @@ #include "../defs/all.h" #include "../defs/mikuart.h" -#include <stdlib.h> -#include <string.h> char **getmikuart(int style){ if(style < 0) @@ -55,6 +53,43 @@ static void freelines(char **lines){ free(lines); } +static char **push_chunk(char **chunks, int *count, const char *start, size_t len){ + chunks = realloc(chunks, (*count + 2) * sizeof(char *)); + chunks[*count] = malloc(len + 1); + memcpy(chunks[*count], start, len); + chunks[*count][len] = '\0'; + (*count)++; + chunks[*count] = NULL; + return chunks; +} + +char **split_word_by_width(const char *word, int max_width){ + char **chunks = NULL; + int count = 0; + size_t length = strlen(word); + size_t start = 0, i = 0; + int chunk_width = 0; + + while(i < length){ + unsigned long codepoint; + int bytes = utf8_decode((const unsigned char *)word + i, &codepoint); + int width = codepoint_width(codepoint); + + if(i > start && chunk_width + width > max_width){ + chunks = push_chunk(chunks, &count, word + start, i - start); + start = i; + chunk_width = 0; + } + chunk_width += width; + i += bytes; + } + + if(i > start) + chunks = push_chunk(chunks, &count, word + start, i - start); + + return chunks; +} + char **wraptext(const char *text, int max, int *count){ char *copy = strdup(text); char *current_line = calloc(strlen(text)+1, sizeof(char)); @@ -69,17 +104,40 @@ char **wraptext(const char *text, int max, int *count){ } strcat(current_line, tok); } else{ - if(current_line[0] != '\0'){ - lines = realloc(lines, (*count + 2) * sizeof(char *)); - lines[*count] = strdup(current_line); - (*count)++; - lines[*count] = NULL; - } - strcpy(current_line, tok); + if(displaywidth(tok) > max){ + if(current_line[0] != '\0'){ + lines = realloc(lines, (*count + 2) * sizeof(char *)); + lines[*count] = strdup(current_line); + (*count)++; + lines[*count] = NULL; + } + + char **chunks = split_word_by_width(tok, max); + int n = 0; + while(chunks[n] != NULL) n++; + + for(int i = 0; i < n - 1; i++){ + lines = realloc(lines, (*count + 2) * sizeof(char *)); + lines[*count] = chunks[i]; + (*count)++; + lines[*count] = NULL; + } + + strcpy(current_line, chunks[n - 1]); + free(chunks[n - 1]); + free(chunks); + } else{ + if(current_line[0] != '\0'){ + lines = realloc(lines, (*count + 2) * sizeof(char *)); + lines[*count] = strdup(current_line); + (*count)++; + lines[*count] = NULL; + } + strcpy(current_line, tok); + } } tok = strtok(NULL, " \t\n"); } - if(current_line[0] != '\0'){ lines = realloc(lines, (*count + 2) * sizeof(char *)); lines[*count] = strdup(current_line); |
