/* * Font lookup and rendering 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 "font.h" #include #include #include #include #include "image.h" #define BIT_TO_BYTE(i) ((i) / CHAR_BIT) #define BITS_TO_BYTES(i) BIT_TO_BYTE((i) + CHAR_BIT - 1) #define BIT_BYTE_SHIFT(i) (CHAR_BIT - 1 - ((i) % CHAR_BIT)) #define FONT_H(f) ((size_t) (f)->desc.height) #define FONT_W(f) ((size_t) (f)->desc.width) #define FONT_W_BYTES(f) BITS_TO_BYTES(FONT_W(f)) struct font { const struct font_desc desc; }; static const struct font_desc *fonts[] = { &font_mplus_1mn_medium_10x14, &font_mplus_1mn_regular_12x17, &font_mplus_1mn_regular_14x19, &font_mplus_1mn_regular_16x22, }; struct font * font_find(const char *name) { size_t i; if (!name) { return (struct font *) fonts[0]; } for (i = 0; i < *(&fonts + 1) - fonts; ++i) { if (strcmp(fonts[i]->name, name) == 0) { return (struct font *) fonts[i]; } } return (struct font *) fonts[0]; } int font_get_width(struct font *font) { return font->desc.width; } int font_get_height(struct font *font) { return font->desc.height; } void font_render(struct font *font, png_const_colorp fg, png_const_colorp bg, char ch, png_bytepp rows, int row, int col) { size_t y; size_t r; size_t x; size_t c; size_t byte; unsigned char font_ch; for (y = 0, r = row * FONT_H(font); y < FONT_H(font); ++y, ++r) { for (x = 0, c = col * FONT_W(font); x < FONT_W(font); ++x, ++c){ byte = ((ch * FONT_H(font)) + y) * FONT_W_BYTES(font) + BIT_TO_BYTE(x); font_ch = font->desc.data[byte]; if ((font_ch >> (BIT_BYTE_SHIFT(x))) & 0x01) { rows[r][c * IMAGE_PIXEL_SIZE + 0] = fg->red; rows[r][c * IMAGE_PIXEL_SIZE + 1] = fg->green; rows[r][c * IMAGE_PIXEL_SIZE + 2] = fg->blue; } else { rows[r][c * IMAGE_PIXEL_SIZE + 0] = bg->red; rows[r][c * IMAGE_PIXEL_SIZE + 1] = bg->green; rows[r][c * IMAGE_PIXEL_SIZE + 2] = bg->blue; } } } }