Fast and reasonably complete (framebuffer) terminal emulator (Zig fork)

Make canvas option not preprocessor gated

mintsuki 986eac0a 5457c7aa

Changed files
+33 -58
backends
+32 -49
backends/fb.c
···
return;
}
-
#ifdef FLANTERM_FB_DISABLE_CANVAS
uint32_t default_bg = ctx->default_bg;
-
#endif
x = ctx->offset_x + x * ctx->glyph_width;
y = ctx->offset_y + y * ctx->glyph_height;
···
for (size_t gy = 0; gy < ctx->glyph_height; gy++) {
uint8_t fy = gy / ctx->font_scale_y;
volatile uint32_t *fb_line = ctx->framebuffer + x + (y + gy) * (ctx->pitch / 4);
-
-
#ifndef FLANTERM_FB_DISABLE_CANVAS
uint32_t *canvas_line = ctx->canvas + x + (y + gy) * ctx->width;
-
#endif
-
for (size_t fx = 0; fx < ctx->font_width; fx++) {
bool draw = glyph[fy * ctx->font_width + fx];
for (size_t i = 0; i < ctx->font_scale_x; i++) {
size_t gx = ctx->font_scale_x * fx + i;
-
#ifndef FLANTERM_FB_DISABLE_CANVAS
-
uint32_t bg = c->bg == 0xffffffff ? canvas_line[gx] : c->bg;
-
uint32_t fg = c->fg == 0xffffffff ? canvas_line[gx] : c->fg;
-
#else
-
uint32_t bg = c->bg == 0xffffffff ? default_bg : c->bg;
-
uint32_t fg = c->fg == 0xffffffff ? default_bg : c->fg;
-
#endif
fb_line[gx] = draw ? fg : bg;
}
}
···
x = ctx->offset_x + x * ctx->glyph_width;
y = ctx->offset_y + y * ctx->glyph_height;
-
#ifdef FLANTERM_FB_DISABLE_CANVAS
uint32_t default_bg = ctx->default_bg;
-
#endif
bool *new_glyph = &ctx->font_bool[c->c * ctx->font_height * ctx->font_width];
bool *old_glyph = &ctx->font_bool[old->c * ctx->font_height * ctx->font_width];
for (size_t gy = 0; gy < ctx->glyph_height; gy++) {
uint8_t fy = gy / ctx->font_scale_y;
volatile uint32_t *fb_line = ctx->framebuffer + x + (y + gy) * (ctx->pitch / 4);
-
#ifndef FLANTERM_FB_DISABLE_CANVAS
uint32_t *canvas_line = ctx->canvas + x + (y + gy) * ctx->width;
-
#endif
for (size_t fx = 0; fx < ctx->font_width; fx++) {
bool old_draw = old_glyph[fy * ctx->font_width + fx];
bool new_draw = new_glyph[fy * ctx->font_width + fx];
···
continue;
for (size_t i = 0; i < ctx->font_scale_x; i++) {
size_t gx = ctx->font_scale_x * fx + i;
-
#ifndef FLANTERM_FB_DISABLE_CANVAS
-
uint32_t bg = c->bg == 0xffffffff ? canvas_line[gx] : c->bg;
-
uint32_t fg = c->fg == 0xffffffff ? canvas_line[gx] : c->fg;
-
#else
-
uint32_t bg = c->bg == 0xffffffff ? default_bg : c->bg;
-
uint32_t fg = c->fg == 0xffffffff ? default_bg : c->fg;
-
#endif
fb_line[gx] = new_draw ? fg : bg;
}
}
···
static void flanterm_fb_full_refresh(struct flanterm_context *_ctx) {
struct flanterm_fb_context *ctx = (void *)_ctx;
-
#ifdef FLANTERM_FB_DISABLE_CANVAS
uint32_t default_bg = ctx->default_bg;
-
#endif
for (size_t y = 0; y < ctx->height; y++) {
for (size_t x = 0; x < ctx->width; x++) {
-
#ifndef FLANTERM_FB_DISABLE_CANVAS
-
ctx->framebuffer[y * (ctx->pitch / sizeof(uint32_t)) + x] = ctx->canvas[y * ctx->width + x];
-
#else
-
ctx->framebuffer[y * (ctx->pitch / sizeof(uint32_t)) + x] = default_bg;
-
#endif
}
}
···
_free(ctx->queue, ctx->queue_size);
_free(ctx->map, ctx->map_size);
-
#ifndef FLANTERM_FB_DISABLE_CANVAS
-
_free(ctx->canvas, ctx->canvas_size);
-
#endif
_free(ctx, sizeof(struct flanterm_fb_context));
}
···
uint8_t red_mask_size, uint8_t red_mask_shift,
uint8_t green_mask_size, uint8_t green_mask_shift,
uint8_t blue_mask_size, uint8_t blue_mask_shift,
-
#ifndef FLANTERM_FB_DISABLE_CANVAS
uint32_t *canvas,
-
#endif
uint32_t *ansi_colours, uint32_t *ansi_bright_colours,
uint32_t *default_bg, uint32_t *default_fg,
uint32_t *default_bg_bright, uint32_t *default_fg_bright,
···
width = width_limit;
height = height_limit;
}
#else
return NULL;
#endif
···
}
memset(ctx->map, 0, ctx->map_size);
-
#ifndef FLANTERM_FB_DISABLE_CANVAS
-
ctx->canvas_size = ctx->width * ctx->height * sizeof(uint32_t);
-
ctx->canvas = _malloc(ctx->canvas_size);
-
if (ctx->canvas == NULL) {
-
goto fail;
-
}
if (canvas != NULL) {
-
for (size_t i = 0; i < ctx->width * ctx->height; i++) {
-
ctx->canvas[i] = convert_colour(_ctx, canvas[i]);
}
-
} else {
for (size_t i = 0; i < ctx->width * ctx->height; i++) {
-
ctx->canvas[i] = ctx->default_bg;
}
}
-
#endif
_ctx->raw_putchar = flanterm_fb_raw_putchar;
_ctx->clear = flanterm_fb_clear;
···
return NULL;
}
-
#ifndef FLANTERM_FB_DISABLE_CANVAS
if (ctx->canvas != NULL) {
_free(ctx->canvas, ctx->canvas_size);
}
-
#endif
if (ctx->map != NULL) {
_free(ctx->map, ctx->map_size);
}
···
return;
}
uint32_t default_bg = ctx->default_bg;
x = ctx->offset_x + x * ctx->glyph_width;
y = ctx->offset_y + y * ctx->glyph_height;
···
for (size_t gy = 0; gy < ctx->glyph_height; gy++) {
uint8_t fy = gy / ctx->font_scale_y;
volatile uint32_t *fb_line = ctx->framebuffer + x + (y + gy) * (ctx->pitch / 4);
uint32_t *canvas_line = ctx->canvas + x + (y + gy) * ctx->width;
for (size_t fx = 0; fx < ctx->font_width; fx++) {
bool draw = glyph[fy * ctx->font_width + fx];
for (size_t i = 0; i < ctx->font_scale_x; i++) {
size_t gx = ctx->font_scale_x * fx + i;
+
uint32_t bg, fg;
+
if (ctx->canvas != NULL) {
+
bg = c->bg == 0xffffffff ? canvas_line[gx] : c->bg;
+
fg = c->fg == 0xffffffff ? canvas_line[gx] : c->fg;
+
} else {
+
bg = c->bg == 0xffffffff ? default_bg : c->bg;
+
fg = c->fg == 0xffffffff ? default_bg : c->fg;
+
}
fb_line[gx] = draw ? fg : bg;
}
}
···
x = ctx->offset_x + x * ctx->glyph_width;
y = ctx->offset_y + y * ctx->glyph_height;
uint32_t default_bg = ctx->default_bg;
bool *new_glyph = &ctx->font_bool[c->c * ctx->font_height * ctx->font_width];
bool *old_glyph = &ctx->font_bool[old->c * ctx->font_height * ctx->font_width];
for (size_t gy = 0; gy < ctx->glyph_height; gy++) {
uint8_t fy = gy / ctx->font_scale_y;
volatile uint32_t *fb_line = ctx->framebuffer + x + (y + gy) * (ctx->pitch / 4);
uint32_t *canvas_line = ctx->canvas + x + (y + gy) * ctx->width;
for (size_t fx = 0; fx < ctx->font_width; fx++) {
bool old_draw = old_glyph[fy * ctx->font_width + fx];
bool new_draw = new_glyph[fy * ctx->font_width + fx];
···
continue;
for (size_t i = 0; i < ctx->font_scale_x; i++) {
size_t gx = ctx->font_scale_x * fx + i;
+
uint32_t bg, fg;
+
if (ctx->canvas != NULL) {
+
bg = c->bg == 0xffffffff ? canvas_line[gx] : c->bg;
+
fg = c->fg == 0xffffffff ? canvas_line[gx] : c->fg;
+
} else {
+
bg = c->bg == 0xffffffff ? default_bg : c->bg;
+
fg = c->fg == 0xffffffff ? default_bg : c->fg;
+
}
fb_line[gx] = new_draw ? fg : bg;
}
}
···
static void flanterm_fb_full_refresh(struct flanterm_context *_ctx) {
struct flanterm_fb_context *ctx = (void *)_ctx;
uint32_t default_bg = ctx->default_bg;
for (size_t y = 0; y < ctx->height; y++) {
for (size_t x = 0; x < ctx->width; x++) {
+
if (ctx->canvas != NULL) {
+
ctx->framebuffer[y * (ctx->pitch / sizeof(uint32_t)) + x] = ctx->canvas[y * ctx->width + x];
+
} else {
+
ctx->framebuffer[y * (ctx->pitch / sizeof(uint32_t)) + x] = default_bg;
+
}
}
}
···
_free(ctx->queue, ctx->queue_size);
_free(ctx->map, ctx->map_size);
+
if (ctx->canvas != NULL) {
+
_free(ctx->canvas, ctx->canvas_size);
+
}
_free(ctx, sizeof(struct flanterm_fb_context));
}
···
uint8_t red_mask_size, uint8_t red_mask_shift,
uint8_t green_mask_size, uint8_t green_mask_shift,
uint8_t blue_mask_size, uint8_t blue_mask_shift,
uint32_t *canvas,
uint32_t *ansi_colours, uint32_t *ansi_bright_colours,
uint32_t *default_bg, uint32_t *default_fg,
uint32_t *default_bg_bright, uint32_t *default_fg_bright,
···
width = width_limit;
height = height_limit;
}
+
+
// Force disable canvas
+
canvas = NULL;
#else
return NULL;
#endif
···
}
memset(ctx->map, 0, ctx->map_size);
if (canvas != NULL) {
+
ctx->canvas_size = ctx->width * ctx->height * sizeof(uint32_t);
+
ctx->canvas = _malloc(ctx->canvas_size);
+
if (ctx->canvas == NULL) {
+
goto fail;
}
for (size_t i = 0; i < ctx->width * ctx->height; i++) {
+
ctx->canvas[i] = convert_colour(_ctx, canvas[i]);
}
}
_ctx->raw_putchar = flanterm_fb_raw_putchar;
_ctx->clear = flanterm_fb_clear;
···
return NULL;
}
if (ctx->canvas != NULL) {
_free(ctx->canvas, ctx->canvas_size);
}
if (ctx->map != NULL) {
_free(ctx->map, ctx->map_size);
}
+1 -9
backends/fb.h
···
#include "../flanterm.h"
-
#ifndef FLANTERM_FB_DISABLE_BUMP_ALLOC
-
# define FLANTERM_FB_DISABLE_CANVAS 1
-
#endif
-
#define FLANTERM_FB_FONT_GLYPHS 256
struct flanterm_fb_char {
···
uint32_t default_fg, default_bg;
uint32_t default_fg_bright, default_bg_bright;
-
#ifndef FLANTERM_FB_DISABLE_CANVAS
size_t canvas_size;
uint32_t *canvas;
-
#endif
size_t grid_size;
size_t queue_size;
···
uint8_t red_mask_size, uint8_t red_mask_shift,
uint8_t green_mask_size, uint8_t green_mask_shift,
uint8_t blue_mask_size, uint8_t blue_mask_shift,
-
#ifndef FLANTERM_FB_DISABLE_CANVAS
-
uint32_t *canvas,
-
#endif
uint32_t *ansi_colours, uint32_t *ansi_bright_colours, // If nulled, default.
uint32_t *default_bg, uint32_t *default_fg, // If nulled, default.
uint32_t *default_bg_bright, uint32_t *default_fg_bright, // If nulled, default.
···
#include "../flanterm.h"
#define FLANTERM_FB_FONT_GLYPHS 256
struct flanterm_fb_char {
···
uint32_t default_fg, default_bg;
uint32_t default_fg_bright, default_bg_bright;
size_t canvas_size;
uint32_t *canvas;
size_t grid_size;
size_t queue_size;
···
uint8_t red_mask_size, uint8_t red_mask_shift,
uint8_t green_mask_size, uint8_t green_mask_shift,
uint8_t blue_mask_size, uint8_t blue_mask_shift,
+
uint32_t *canvas, // If nulled, no canvas.
uint32_t *ansi_colours, uint32_t *ansi_bright_colours, // If nulled, default.
uint32_t *default_bg, uint32_t *default_fg, // If nulled, default.
uint32_t *default_bg_bright, uint32_t *default_fg_bright, // If nulled, default.