diff options
Diffstat (limited to 'src/text.c')
-rw-r--r-- | src/text.c | 59 |
1 files changed, 40 insertions, 19 deletions
@@ -21,6 +21,7 @@ #include "text.h" +#include <stdio.h> #include <stdlib.h> #include <string.h> @@ -32,19 +33,39 @@ #define MAX(a, b) (((a) > (b)) ? (a) : (b)) struct text { - const char *string; - size_t width; - size_t height; + size_t size; + size_t read; + char *string; + size_t width; + size_t height; }; +static char +_getc(struct text *text, FILE *stream, char *c) +{ + int i_c; + + if (text->read == text->size) { + text->size += 8192; + text->string = realloc(text->string, text->size); + } + + i_c = fgetc(stream); + if (i_c == EOF) { + i_c = 0; + } + return text->string[text->read++] = *c = i_c; +} + struct text * -text_new(const char *string) +text_new(FILE *stream) { struct text *text; size_t width; int eol; + char c; - if (!string) { + if (!stream) { return NULL; } text = calloc(1, sizeof(*text)); @@ -52,28 +73,27 @@ text_new(const char *string) return NULL; } - text->string = string; - width = 0; eol = 0; - while (string && *string) { - if (*string == 0x1B && *(string + 1) == '[') { /* CSI */ - string += 2; - for (; *string >= 0x30 && *string <= 0x3F; ++string); - for (; *string >= 0x20 && *string <= 0x2F; ++string); - if (*string >= 0x40 && *string <= 0x7E) { - ++string; + _getc(text, stream, &c); + while (c) { + if (c == 0x1B && _getc(text, stream, &c) == '[') { /* CSI */ + _getc(text, stream, &c); + for (; c >= 0x30 && c <= 0x3F; _getc(text, stream, &c)); + for (; c >= 0x20 && c <= 0x2F; _getc(text, stream, &c)); + if (c >= 0x40 && c <= 0x7E) { + _getc(text, stream, &c); } eol = 0; - } else if (*string == '\n') { + } else if (c == '\n') { text->width = MAX(text->width, width); width = 0; ++text->height; - ++string; + _getc(text, stream, &c); eol = 1; } else { ++width; - ++string; + _getc(text, stream, &c); eol = 0; } } @@ -129,8 +149,8 @@ text_render(struct text *text, struct font *font, png_bytepp rows) row = 0; col = 0; while (string && *string) { - if (*string == 0x1B && *(string + 1) == '[') { /* CSI */ - string += 2; + if (*string == 0x1B && *(++string) == '[') { /* CSI */ + ++string; parameter = string; for (; *string >= 0x30 && *string <= 0x3F; ++string); for (; *string >= 0x20 && *string <= 0x2F; ++string); @@ -171,6 +191,7 @@ text_destroy(struct text **text_p) text = *text_p; + free(text->string); free(text); return text = NULL; } |