libtthimage/Lib/text16x24.c

335 lines
8.1 KiB
C

/*
* textes en 16x24
* ---------------
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "../tthimage.h"
/*::------------------------------------------------------------------::*/
typedef struct {
short flags;
uint16_t bits[24];
} Char_16x24;
/* go, go, go, have a global var */
/* 14 septembre 2020, make it static */
static Char_16x24 chars_16x24[256];
/*::------------------------------------------------------------------::*/
/*
il n'y a encore rien dans cette fonction, car je suis en train
de construire un éditeur de fonte adapté a _mes_ besoins.
dès qu'il commencera a etre utilisable, et surtout dès que les
spécifications du format de fichier seront relativement figées,
je commencerais à coder la chose.
*/
/* 15 septembre 2022 : rien n'est fait, c'est un scandale ! */
int Image_t16x24_binload(char *fontname, uint8_t *zone, int flag)
{
fprintf(stderr, "Don't know how to load '%s' in binary mode\n", fontname);
fprintf(stderr, " address %p flags 0x%x\n", zone, flag);
return FUNC_NOT_FINISH;
}
/*::------------------------------------------------------------------::*/
/* WARNING: this function is a work in progress */
int Image_t16x24_txtload(char *fontname, uint8_t *zone, int flags)
{
FILE *fp;
int numchar;
int foo, x, y, eol, mask;
char ligne[20+1];
uint16_t mot;
fprintf(stderr, ">>> %s ( '%s' %p 0x%x )\n", __func__, fontname, zone, flags);
if ( NULL == (fp=Image_must_fopen(fontname, "r", 0)) ) {
fprintf(stderr, "can't open %s\n", fontname);
return FILE_NOT_FOUND;
}
/* 16 juin 2015 : now we can erase the whole font by
setting bit 0 of flags to one */
if (flags & 1) {
fprintf(stderr, "%s: erasing 16x24 font for %s\n", __func__, fontname);
memset(chars_16x24, 0, sizeof(chars_16x24));
}
while ( 1 == fscanf(fp, "%d\n", &numchar) ) {
if ( (numchar<0) || (numchar>255) ) {
fprintf(stderr, "char %d out of range\n", numchar);
break;
}
#if DEBUG_LEVEL > 1
fprintf(stderr, "-- char %3d '%c'\n", numchar,
isprint(numchar) ? numchar : ' ');
#endif
for (y=0; y<24; y++) {
/* lecture d'une ligne d'ascii-pixels */
memset(ligne, '\0', 20);
if ( NULL==fgets(ligne, 20, fp) )
{
fprintf(stderr, "EOF ?\n");
}
foo = strlen(ligne);
eol = ligne[16];
if (17!=foo || '\n'!=eol)
{
fprintf(stderr, "%s: bad line: %3d %3d %3d\n",
__func__, y, foo, eol);
fprintf(stderr, " [%s]\n", ligne);
abort(); /* very hard, no ? XXX */
}
mask = 0x8000;
mot = 0;
for (x=0; x<16; x++)
{
if (ligne[x]=='*' || ligne[x]=='0')
{
mot |= mask;
#if DEBUG_LEVEL > 1
putchar('O');
#endif
}
/* ahem, ne serait-il pas bon de filtrer un peu plus les
* caracteres indesirables ? */
#if DEBUG_LEVEL > 1
else
putchar(' ');
#endif
mask >>= 1;
}
#if DEBUG_LEVEL > 1
printf(" | %04x\n", mot);
#endif
chars_16x24[numchar].bits[y] = mot;
}
/* fin de la boucle sur les caracteres dans le fichier */
}
fclose(fp);
return 0;
}
/*::------------------------------------------------------------------::*/
int Image_t16x24_pltch_exp(Image_Desc *img, int lettre, int xpos, int ypos)
{
int x, y;
uint16_t mask;
#if DEBUG_LEVEL > 1
fprintf(stderr, "%s: lettre %3d '%c' %4d %4d\n", __func__, lettre,
isprint(lettre) ? lettre : ' ', xpos, ypos);
#endif
for (x=0; x<16; x++)
for (y=0; y<24; y++)
Image_plotRGB(img, x+xpos, y+ypos, 60, 60, 80);
for (y=0; y<24; y++) {
mask = 0x8000;
for (x=0; x<16; x++) {
if (chars_16x24[lettre].bits[y] & mask) {
#if DEBUG_LEVEL > 2
putchar('X');
#endif
Image_plotRGB(img, x+xpos, y+ypos, 200, 200, 250);
}
#if DEBUG_LEVEL > 2
else putchar('-');
#endif
mask >>= 1;
}
#if DEBUG_LEVEL > 2
putchar('\n');
#endif
}
return FUNC_IS_BETA;
}
/*::------------------------------------------------------------------::*/
int Image_t16x24_pltch_1(Image_Desc *img, int lettre, int xpos, int ypos,
RGBA *pap, RGBA *ink, int flags)
{
int x, y, rs, gs, bs;
int rp, gp, bp;
int x2, y2;
uint16_t mask;
RGBA blanc = { 255, 255, 255, 255, 0, 0 },
noir = { 0, 0, 0, 64, 0, 0 };
if (flags) {
fprintf(stderr, "in %s, useless flags 0x%x is useless\n",
__func__, flags);
}
#if DEBUG_LEVEL > 1
fprintf(stderr, "%s: ltr %3d '%c' %4d %4d\n", __func__, lettre,
isprint(lettre) ? lettre : ' ', xpos, ypos);
#endif
/*
* use default if not provided by caller
*/
if (NULL==pap) pap = &blanc;
if (NULL==ink) ink = &noir;
/* +-------------------------------+
| WTF ? no boundary check ? |
+-------------------------------+ */
for (y=0; y<24; y++) {
mask = 0x8000;
y2 = y + ypos;
for (x=0; x<16; x++) {
x2 = x + xpos;
Image_getRGB(img, x2, y2, &rs, &gs, &bs);
if (chars_16x24[lettre].bits[y] & mask) {
#if DEBUG_LEVEL > 1
putchar('O');
#endif
rp = ((rs*(255-ink->a))+(ink->r*ink->a)) / 255;
gp = ((gs*(255-ink->a))+(ink->g*ink->a)) / 255;
bp = ((bs*(255-ink->a))+(ink->b*ink->a)) / 255;
}
else {
#if DEBUG_LEVEL > 1
putchar('.');
#endif
rp = ((rs*(255-pap->a))+(pap->r*pap->a)) / 255;
gp = ((gs*(255-pap->a))+(pap->g*pap->a)) / 255;
bp = ((bs*(255-pap->a))+(pap->b*pap->a)) / 255;
}
Image_plotRGB(img, x2, y2, rp, gp, bp);
mask >>= 1;
} /* finbo x */
#if DEBUG_LEVEL > 1
putchar('\n');
#endif
} /* finbo y */
return FUNC_IS_BETA;
}
/*::------------------------------------------------------------------::*/
int Image_t16x24_pltstr_1(Image_Desc *img, char *str, int x, int y,
RGBA *paper, RGBA *ink, int flags)
{
int len, foo;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s: '%s' at %d,%d\n", __func__, str, x, y);
#endif
len = strlen(str);
for (foo=0; foo<len; foo++) {
#if DEBUG_LEVEL > 1
fprintf(stderr, "%4d %c\n", foo, str[foo]);
#endif
Image_t16x24_pltch_1(img, str[foo], x+(foo*16), y, paper, ink, flags);
}
/* XXX return FUNC_IS_BETA; */
return 0;
}
/*::------------------------------------------------------------------::*/
/*::------------------------------------------------------------------::*/
#define T_ZONE (256*24*2) /* please explain this magic number */
int Image_t16x24_essai(char *fontname, char *texte, char *tganame)
{
Image_Desc *img;
int foo;
int ltxt, largeur;
fprintf(stderr, "*** essai fonte 16x24: %s -> %s\n", fontname, tganame);
fprintf(stderr, " texte -> '%s'\n", texte);
foo = Image_t16x24_txtload(fontname, NULL, 0);
Image_print_error("fonte 16x24, txtload", foo);
ltxt = strlen(texte);
largeur = 16 * ltxt;
img = Image_alloc(largeur, 24, 3);
if (NULL == img) {
fprintf(stderr, "no mem in %s\n", __func__);
abort();
}
Image_clear(img, 0, 0, 0);
for (foo=0; foo<ltxt; foo++) {
Image_t16x24_pltch_exp(img, texte[foo], foo*16, 0);
}
foo = Image_TGA_save(tganame, img, 0);
Image_DeAllocate(img);
return FUNC_NOT_FINISH;
}
/*::------------------------------------------------------------------::*/
#define S_X (34)
#define S_Y (37)
#define W_IMG (8+(16*S_X))
#define H_IMG (10+(16*S_Y))
int Image_t16x24_chars_map(char *fontname, char *tganame, int flag)
{
Image_Desc *img;
int foo, ix, iy, ichar;
int px, py;
char chaine[42];
RGBA paper, ink;
foo = Image_t16x24_txtload(fontname, NULL, flag & 2);
if (foo) {
fprintf(stderr, "%s: file %s not found\n", __func__, fontname);
Image_print_error("fonte 16x24, txtload", foo);
return foo;
}
img = Image_alloc(W_IMG, H_IMG, 3);
if (NULL == img) {
fprintf(stderr, "no mem in %s\n", __func__);
abort();
}
Image_clear(img, 0, 0, 0);
Image_load_fnt8x8("8x8thin", NULL, 0);
paper.r = paper.g = paper.b = paper.a = 0;
ink.r = ink.g = ink.b = 192; ink.a = 255;
ichar = 0;
for (ix=0; ix<16; ix++) {
px = 4 + (ix * S_X);
for (iy=0; iy<16; iy++) {
py = 4 + (iy * S_Y);
Image_t16x24_pltch_exp(img, ichar, px+4, py);
if (flag & 1)
sprintf(chaine, "$%02x", ichar);
else
sprintf(chaine, "%3d", ichar);
Image_trace_chaine_1(img, chaine, px, py+25, NULL,
&paper, &ink);
ichar ++;
}
}
foo = Image_TGA_save(tganame, img, 0);
Image_DeAllocate(img); free(img);
return OLL_KORRECT;
}
/*::------------------------------------------------------------------::*/