libcdsb/src/string/extra-align.c

143 lines
2.5 KiB
C

/* This software is licensed by the MIT License, see LICENSE file */
/* Copyright © 2022 Gregory Lirent */
#include "include.h"
/*#####################################################################################################################*/
static char* string_info(const vtype_string* s, size_t* size, size_t* nmemb) {
char* p;
char* v;
if (is_null(s->buffer) || !*s->buffer) {
*size = *nmemb = 0;
return s->buffer;
}
*size = *nmemb = strasciilen(s->buffer);
p = s->buffer + *nmemb;
if (!*p) return p;
while (*(v = next_char(p))) {
++*size;
*nmemb += v - p;
p = v;
}
++*size;
*nmemb += v - p;
return p;
}
static int fetch_pad(char buffer[4], int chr) {
char* p;
if (chr) {
p = tochar_unicode(buffer, chr);
chr = !is_null(p) ? p - buffer : 0;
}
if (!chr) {
*buffer = ' ';
chr = 1;
}
return chr;
}
/*#####################################################################################################################*/
size_t string_align_center(vtype_string* x, size_t n, int pc) {
char s[4];
size_t l;
size_t ls;
size_t rs;
char* p;
string_info(x, &ls, &l);
if (ls < n) {
pc = fetch_pad(s, pc);
ls = n - ls;
rs = ls / 2;
} else return ls;
x->buffer = p = realloc(x->buffer, l + ls*pc + 1);
memmove(x->buffer + (ls -= rs)*pc, x->buffer, l);
for (size_t i = 0; i < ls; ++i) {
p = memcpy(p, s, pc) + pc;
}
p += l;
for (size_t i = 0; i < rs; ++i) {
p = memcpy(p, s, pc) + pc;
}
*p = 0;
return n;
}
size_t string_align_right(vtype_string* x, size_t n, int pc) {
char s[4];
size_t l;
size_t ls;
char* p;
string_info(x, &ls, &l);
if (ls < n) {
pc = fetch_pad(s, pc);
ls = n - ls;
} else return ls;
x->buffer = p = realloc(x->buffer, ++l + ls*pc);
memmove(x->buffer + ls*pc, x->buffer, l);
for (size_t i = 0; i < ls; ++i) {
p = memcpy(p, s, pc) + pc;
}
return n;
}
size_t string_align_left(vtype_string* x, size_t n, int pc) {
char s[4];
size_t l;
size_t rs;
char* p;
string_info(x, &rs, &l);
if (rs < n) {
pc = fetch_pad(s, pc);
rs = n - rs;
} else return rs;
x->buffer = realloc(x->buffer, l + rs*pc + 1);
p = x->buffer + l;
for (size_t i = 0; i < rs; ++i) {
p = memcpy(p, s, pc) + pc;
}
*p = 0;
return n;
}