/* * Text layout and parsing functions * * Copyright (C) 2019 Patrick McDermott * * This file is part of fbcon2png. * * fbcon2png is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * fbcon2png is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with fbcon2png. If not, see . */ #include "text.h" #include #include #include "font.h" #define MAX(a, b) (((a) > (b)) ? (a) : (b)) struct text { const char *string; int width; int height; }; struct text * text_new(const char *string) { struct text *text; int width; int eol; if (!string) { return NULL; } text = calloc(1, sizeof(*text)); if (!text) { 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; } eol = 0; } else if (*string == '\n') { text->width = MAX(text->width, width); width = 0; ++text->height; ++string; eol = 1; } else { ++width; ++string; eol = 0; } } if (!eol) { ++text->height; } return text; } int text_get_width(struct text *text) { return text->width; } int text_get_height(struct text *text) { return text->height; } void text_render(struct text *text, struct font *font, png_bytepp rows) { const char *string; size_t row; size_t col; png_color fg = {255, 255, 255}; png_color bg = { 0, 0, 0}; string = text->string; row = 0; col = 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; } } else if (*string == '\n') { for (; col < text->width; ++col) { font_render(font, &fg,&bg, ' ', rows, row, col); } col = 0; ++row; ++string; } else { font_render(font, &fg, &bg, *string, rows, row, col); ++col; ++string; } } for (; col < text->width; ++col) { font_render(font, &fg, &bg, ' ', rows, row, col); } } struct text * text_destroy(struct text **text_p) { struct text *text; text = *text_p; free(text); return text = NULL; }