From 6c19190175b2b22394e3419c7072fcbec0e9335f Mon Sep 17 00:00:00 2001 From: Axollyon <20480418+Axollyon@users.noreply.github.com> Date: Wed, 24 Feb 2021 12:28:46 -0500 Subject: [PATCH] Text alignment and reset character (#1) Co-authored-by: Axollyon --- config.h | 3 ++ s2d_parse.c | 132 ++++++++++++++++++++++++++++++++++++++++++++++------ s2d_print.h | 14 ++++-- 3 files changed, 130 insertions(+), 19 deletions(-) diff --git a/config.h b/config.h index 482fda23..5492e9d2 100644 --- a/config.h +++ b/config.h @@ -47,6 +47,9 @@ extern char *proutSprintf(char *dst, const char *src, size_t count); #define TEX_HEIGHT 16 #define TEX_BITDEPTH 8 +// Texture resolution (pixels on the texture per pixel on the framebuffer) +#define TEX_RES 1 + #define _NUM_CACHE (4096 / (TEX_WIDTH * TEX_HEIGHT * (TEX_BITDEPTH / 8))) #endif \ No newline at end of file diff --git a/s2d_parse.c b/s2d_parse.c index f5a64723..af417984 100644 --- a/s2d_parse.c +++ b/s2d_parse.c @@ -9,11 +9,12 @@ #include "s2d_print.h" #include "s2d_ustdlib.h" -void s2d_snprint(int x, int y, const char *str, uObjMtx *buf, int len) { +void s2d_snprint(int x, int y, int align, const char *str, uObjMtx *buf, int len) { char *p = str; int tmp_len = 0; int orig_x = x; int orig_y = y; + int line = 0; if (*p == '\0') return; @@ -23,6 +24,15 @@ void s2d_snprint(int x, int y, const char *str, uObjMtx *buf, int len) { s2d_red = s2d_green = s2d_blue = 255; s2d_alpha = 255; drop_shadow = FALSE; + + switch (align) { + case ALIGN_CENTER: + x = orig_x - s2d_width(str, line, len) / 2; + break; + case ALIGN_RIGHT: + x = orig_x - s2d_width(str, line, len); + } + do { char current_char = *p; @@ -37,10 +47,22 @@ void s2d_snprint(int x, int y, const char *str, uObjMtx *buf, int len) { break; case CH_TRANSLATE: CH_SKIP(p); - x = s2d_atoi(p, &p); + orig_x = s2d_atoi(p, &p); + line++; + switch (align) { + case ALIGN_LEFT: + x = orig_x; + break; + case ALIGN_CENTER: + x = orig_x - s2d_width(str, line, len) / 2; + break; + case ALIGN_RIGHT: + x = orig_x - s2d_width(str, line, len); + } CH_SKIP(p); CH_SKIP(p); - y = s2d_atoi(p, &p); + orig_y = s2d_atoi(p, &p); + y = orig_y; break; case CH_COLOR: CH_SKIP(p); @@ -60,19 +82,36 @@ void s2d_snprint(int x, int y, const char *str, uObjMtx *buf, int len) { // CH_SKIP(p); break; case '\n': - x = orig_x; - y += TEX_HEIGHT; + line++; + switch (align) { + case ALIGN_LEFT: + x = orig_x; + break; + case ALIGN_CENTER: + x = orig_x - s2d_width(str, line, len) / 2; + break; + case ALIGN_RIGHT: + x = orig_x - s2d_width(str, line, len); + } + y += TEX_HEIGHT / TEX_RES; break; case '\t': - x += TAB_WIDTH_H; + x += TAB_WIDTH_H / TEX_RES; break; case '\v': - x += TAB_WIDTH_V; - y += TEX_HEIGHT; + x += TAB_WIDTH_V / TEX_RES; + y += TEX_HEIGHT / TEX_RES; break; // case CH_SEPARATOR: // CH_SKIP(p); // break; + case CH_RESET: + s2d_red = s2d_green = s2d_blue = 255; + s2d_alpha = 255; + drop_shadow = FALSE; + myScale = 1; + myDegrees = 0; + break; default: if (current_char != '\0' && current_char != CH_SEPARATOR) { draw_s2d_glyph(current_char, x, y, (buf++)); @@ -87,19 +126,19 @@ void s2d_snprint(int x, int y, const char *str, uObjMtx *buf, int len) { myDegrees = 0; } -void s2d_print(int x, int y, const char *str, uObjMtx *buf) { - s2d_snprint(x, y, str, buf, s2d_strlen(str)); +void s2d_print(int x, int y, int align, const char *str, uObjMtx *buf) { + s2d_snprint(x, y, align, str, buf, s2d_strlen(str)); } -void s2d_print_alloc(int x, int y, const char *str) { +void s2d_print_alloc(int x, int y, int align, const char *str) { uObjMtx *b = alloc(sizeof(uObjMtx) * s2d_strlen(str)); - s2d_snprint(x, y, str, b, s2d_strlen(str)); + s2d_snprint(x, y, align, str, b, s2d_strlen(str)); } -void s2d_type_print(int x, int y, const char *str, uObjMtx *buf, int *pos) { +void s2d_type_print(int x, int y, int align, const char *str, uObjMtx *buf, int *pos) { int len = s2d_strlen(str); - s2d_snprint(x, y, str, buf, *pos); + s2d_snprint(x, y, align, str, buf, *pos); if (s2d_timer % 2 == 0) { if (*pos < len) { (*pos)++; @@ -107,7 +146,70 @@ void s2d_type_print(int x, int y, const char *str, uObjMtx *buf, int *pos) { } } -// void s2d_vsprint(int x, int y, uObjMtx *buf, const char *str, ...) { +int s2d_width(const char *str, int line, int len) { + char *p = str; + int tmp_len = 0; + int curLine = 0; + int width = 0; + int scale = 1; + + if (*p == '\0') return width; + + do { + char current_char = *p; + switch (current_char) { + case CH_SCALE: + CH_SKIP(p); + scale = s2d_atoi(p, &p); + break; + case CH_ROT: + CH_SKIP(p); + s2d_atoi(p, &p); + break; + case CH_TRANSLATE: + CH_SKIP(p); + s2d_atoi(p, &p); + curLine++; + CH_SKIP(p); + CH_SKIP(p); + s2d_atoi(p, &p); + break; + case CH_COLOR: + CH_SKIP(p); + s2d_atoi(p, &p); + CH_SKIP(p); CH_SKIP(p); + s2d_atoi(p, &p); + CH_SKIP(p); CH_SKIP(p); + s2d_atoi(p, &p); + CH_SKIP(p); CH_SKIP(p); + s2d_atoi(p, &p); + break; + case CH_DROPSHADOW: + case CH_RESET: + break; + case '\n': + curLine++; + break; + case '\t': + if (curLine == line) + width += TAB_WIDTH_H / TEX_RES; + break; + case '\v': + if (curLine == line) + width += TAB_WIDTH_V / TEX_RES; + break; + default: + if (current_char != '\0' && curLine == line) + width += s2d_kerning_table[current_char] * scale; + } + if (*p == '\0') break; + p++; + tmp_len++; + } while (tmp_len < len && curLine <= line); + return width; +} + +// void s2d_vsprint(int x, int y, int align, uObjMtx *buf, const char *str, ...) { // int last_chr; // va_list args; // char *dst = alloc(s2d_strlen(str) * 2); diff --git a/s2d_print.h b/s2d_print.h index 901f4f3a..d1b098e3 100644 --- a/s2d_print.h +++ b/s2d_print.h @@ -8,6 +8,7 @@ #define DROPSHADOW "\x84" // DROPSHADOW (no params) #define BACKGROUND "\x85" // BACKGROUND (w) (h) (alpha) #define SEPARATOR "\x86" +#define RESET "\x87" #define CH_SCALE '\x80' #define CH_ROT '\x81' @@ -16,6 +17,7 @@ #define CH_DROPSHADOW '\x84' #define CH_BACKGROUND '\x85' #define CH_SEPARATOR '\x86' +#define CH_RESET '\x87' // ASCII standard escape codes #define CH_NEWLINE '\n' @@ -23,7 +25,11 @@ #define CH_GET_NEXT(x) (*(++x)) #define CH_SKIP(x) {x++;} -extern void s2d_snprint(int x, int y, const char *str, uObjMtx *buf, int len); -extern void s2d_print(int x, int y, const char *str, uObjMtx *buf); -extern void s2d_type_print(int x, int y, const char *str, uObjMtx *buf, int *pos); -extern void s2d_vsprint(int x, int y, uObjMtx *buf, const char *str, ...); +#define ALIGN_LEFT 0 +#define ALIGN_CENTER 1 +#define ALIGN_RIGHT 2 + +extern void s2d_snprint(int x, int y, int align, const char *str, uObjMtx *buf, int len); +extern void s2d_print(int x, int y, int align, const char *str, uObjMtx *buf); +extern void s2d_type_print(int x, int y, int align, const char *str, uObjMtx *buf, int *pos); +extern void s2d_vsprint(int x, int y, int align, uObjMtx *buf, const char *str, ...);