291 lines
6.7 KiB
C
291 lines
6.7 KiB
C
/*
|
||
text0.c
|
||
-------
|
||
|
||
ce module est en phase de 'reflexion'. je n'ai pas la moindre
|
||
idee sur l'organisation de la chose. je pense utiliser les
|
||
fontes bitmap de la console PC.
|
||
|
||
28 Fev 2001: now the standard font is loaded from the file
|
||
/usr/local/share/libimage.fonte
|
||
|
||
*/
|
||
|
||
#include <stdio.h>
|
||
#include <unistd.h>
|
||
#include <stdlib.h>
|
||
#include <ctype.h>
|
||
#include <sys/types.h>
|
||
#include <sys/stat.h>
|
||
#include <fcntl.h>
|
||
#include <string.h>
|
||
|
||
#include "../tthimage.h"
|
||
|
||
#define T_FONTE 2048
|
||
|
||
static uint8_t priv_fonte[T_FONTE];
|
||
static int font_is_loaded;
|
||
|
||
/*::------------------------------------------------------------------::*/
|
||
/*
|
||
* for now, parameter *ou must be NULL
|
||
*/
|
||
int Image_load_fnt8x8(char *nomfnt, uint8_t *ou, int flags)
|
||
{
|
||
int fd, foo;
|
||
|
||
#if DEBUG_LEVEL > 1
|
||
fprintf(stderr, ">>> %s ( '%s' %p %d )\n", __func__, nomfnt, ou, flags);
|
||
#endif
|
||
|
||
if (NULL != ou)
|
||
fprintf(stderr, "in %s, 'ou' (%p) must be NULL\n", __func__, ou);
|
||
if (0 != flags)
|
||
fprintf(stderr, "in %s, 'flags' (%d) must be 0\n", __func__, flags);
|
||
|
||
/* patch du 24 septembre 2015 */
|
||
if (NULL == nomfnt) {
|
||
nomfnt = "libimage.fonte";
|
||
#if DEBUG_LEVEL
|
||
fprintf(stderr, " using default font '%s'\n", nomfnt);
|
||
#endif
|
||
}
|
||
/* on pourrait aussi mettre la fonte par ddefaut dans l'environ */
|
||
|
||
if ( (fd=Image_must_open(nomfnt, O_RDONLY, 0)) < 0 ) {
|
||
perror (nomfnt);
|
||
exit(5);
|
||
}
|
||
|
||
/*
|
||
* Maybe add a check on the size of the file ?
|
||
*/
|
||
|
||
foo = read(fd, priv_fonte, T_FONTE);
|
||
if ( foo != T_FONTE ) {
|
||
fprintf(stderr, "%s: read only %d bytes from font file\n", __func__, foo);
|
||
exit(5);
|
||
}
|
||
close(fd);
|
||
|
||
#if DEBUG_LEVEL > 1
|
||
fprintf(stderr, "%s : font '%s' loaded\n", __func__, nomfnt);
|
||
#endif
|
||
|
||
font_is_loaded = 1;
|
||
|
||
return OLL_KORRECT;
|
||
}
|
||
/*::------------------------------------------------------------------::*/
|
||
/*
|
||
* XXX nasty bug in the alpha channel gestion XXX
|
||
*/
|
||
int Image_trace_caractere_2(Image_Desc *im, uint8_t *fnt, int x, int y, int code,
|
||
RGBA *paper, RGBA *ink)
|
||
{
|
||
int foo, bar, xi, yi;
|
||
int rp, gp, bp, rs, gs, bs;
|
||
uint8_t octet;
|
||
|
||
#if DEBUG_LEVEL > 2
|
||
fprintf(stderr, "trace car 2: xy= %4d %4d c= %c\n", x, y,
|
||
isprint(code) ? code : ' ');
|
||
#endif
|
||
|
||
if (NULL==fnt) {
|
||
fnt = priv_fonte; /* use local static storage */
|
||
}
|
||
|
||
for (foo=0; foo<8; foo++) {
|
||
yi = y+foo;
|
||
octet = fnt[(code*8)+foo];
|
||
for (bar=0; bar<8; bar++) {
|
||
xi = x+7-bar;
|
||
|
||
/* lecture contenu image */
|
||
rs = (im->Rpix[yi])[xi];
|
||
gs = (im->Gpix[yi])[xi];
|
||
bs = (im->Bpix[yi])[xi];
|
||
|
||
if (octet & 1) { /* ENCRE */
|
||
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 { /* PAPIER */
|
||
rp = ((rs*(255-paper->a))+(paper->r*paper->a)) / 255;
|
||
gp = ((gs*(255-paper->a))+(paper->g*paper->a)) / 255;
|
||
bp = ((bs*(255-paper->a))+(paper->b*paper->a)) / 255;
|
||
}
|
||
(im->Rpix[yi])[xi] = rp;
|
||
(im->Gpix[yi])[xi] = gp;
|
||
(im->Bpix[yi])[xi] = bp;
|
||
|
||
octet >>= 1;
|
||
}
|
||
}
|
||
return 42;
|
||
}
|
||
/*::------------------------------------------------------------------::*/
|
||
/*
|
||
* fonction tr<74>s primitive...
|
||
*/
|
||
int Image_trace_caractere(Image_Desc *im, int x, int y, int code)
|
||
{
|
||
int foo, bar;
|
||
uint8_t octet;
|
||
|
||
for (foo=0; foo<8; foo++) {
|
||
octet = priv_fonte[(code*8)+foo];
|
||
for (bar=0; bar<8; bar++) {
|
||
if (octet & 1)
|
||
Image_plotRGB(im, x+8-bar, y+foo, 255, 255, 255);
|
||
else
|
||
Image_plotRGB(im, x+8-bar, y+foo, 0, 0, 5);
|
||
octet >>= 1;
|
||
}
|
||
}
|
||
|
||
return 42;
|
||
}
|
||
/*::------------------------------------------------------------------::*/
|
||
/*
|
||
* trace d'une chaine. (param 'flag' not used)
|
||
* OBSOLETE FUNCTION !
|
||
*/
|
||
int Image_trace_chaine_0(Image_Desc *im, char *txt, int x, int y,
|
||
RGBA *paper, RGBA *ink, int flags)
|
||
{
|
||
int foo;
|
||
|
||
fprintf(stderr, "THE FUNCTION '%s' IS OBSOLETE\n", __func__);
|
||
if (0 != flags)
|
||
fprintf(stderr, "in %s, 'flags' (%d) must be 0\n", __func__, flags);
|
||
|
||
foo = Image_trace_chaine_1(im, txt, x, y, "libimage.fonte", paper, ink);
|
||
|
||
return foo;
|
||
}
|
||
/*::------------------------------------------------------------------::*/
|
||
/*
|
||
* trace d'une chaine avec choix eventuel de la fonte par le
|
||
* nom du fichier. Si celui-ci est NULL, c'est la fonte actuelle
|
||
* qui est utilise.
|
||
*/
|
||
int Image_trace_chaine_1(Image_Desc *im, char *txt, int x, int y,
|
||
char *nomfonte, RGBA *paper, RGBA *ink)
|
||
{
|
||
int posx, posy, t_texte, foo;
|
||
int octet;
|
||
uint8_t *ptrtxt;
|
||
RGBA blanc = { 255, 255, 255, 255, 0, 0 };
|
||
RGBA noir = { 0, 0, 0, 64, 0, 0 };
|
||
|
||
#if DEBUG_LEVEL
|
||
fprintf(stderr, ">>> %s ( %p '%s' %d %d '%s' %p %p\n", __func__,
|
||
im, txt, x, y, nomfonte, paper, ink);
|
||
#endif
|
||
|
||
if (NULL == nomfonte) {
|
||
#if DEBUG_LEVEL > 1
|
||
fprintf(stderr, "trace chaine 1: using loaded font\n");
|
||
#endif
|
||
}
|
||
else {
|
||
#if DEBUG_LEVEL > 1
|
||
fprintf(stderr, "trace chaine 1: loading font '%s'\n", nomfonte);
|
||
#endif
|
||
foo = Image_load_fnt8x8(nomfonte, NULL, 0);
|
||
}
|
||
|
||
if (NULL==paper) paper = &blanc;
|
||
if (NULL==ink) ink = &noir;
|
||
|
||
#if DEBUG_LEVEL
|
||
Image_print_rgba("encre", ink, 0);
|
||
Image_print_rgba("papier", paper, 0);
|
||
#endif
|
||
|
||
t_texte = strlen(txt);
|
||
ptrtxt = (uint8_t *)txt;
|
||
|
||
#if DEBUG_LEVEL > 1
|
||
fprintf(stderr, "texte %3d %s\n", t_texte, txt);
|
||
fprintf(stderr, "papier %3d %3d %3d %3d\n", paper->r, paper->g, paper->b, paper->a);
|
||
fprintf(stderr, "encre %3d %3d %3d %3d\n", ink->r, ink->g, ink->b, ink->a);
|
||
#endif
|
||
|
||
posx = x; posy = y;
|
||
for (foo=0; foo<t_texte; foo++) {
|
||
octet = ptrtxt[foo];
|
||
if (posx > (im->width-8)) {
|
||
fprintf(stderr, "can't plot char '%c' at x=%d\n", octet, posx);
|
||
break;
|
||
}
|
||
Image_trace_caractere_2(im, priv_fonte, posx, posy, octet, paper, ink);
|
||
posx += 8;
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
/*::------------------------------------------------------------------::*/
|
||
/* new --> Sun Feb 2 20:17:34 CET 2014 */
|
||
/*
|
||
* Don't forget to load a font, eg :
|
||
* Image_load_fnt8x8("8x8thin", NULL, 0);
|
||
*/
|
||
int Image_trace_big_char_0(Image_Desc *im, int x, int y, int code, int kx, int ky)
|
||
{
|
||
int foo, bar;
|
||
uint8_t octet;
|
||
Image_Rect rect;
|
||
RGBA paper, ink;
|
||
|
||
#if DEBUG_LEVEL
|
||
char buff[20];
|
||
if (isprint(code)) sprintf(buff, "'%c'", code);
|
||
else sprintf(buff, "%02xh", code);
|
||
fprintf(stderr, "%s ( %p %4d %4d %s %d %d )\n", __func__, im,
|
||
x, y, buff, kx, ky);
|
||
#endif
|
||
|
||
if ( (code < 0) || (code > 255)) {
|
||
fprintf(stderr, "in %s, code (%d) is invalid\n", __func__, code);
|
||
return BAD_PARAMETER;
|
||
}
|
||
|
||
/* Image_load_fnt8x8("8x8thin", NULL, 0); */
|
||
|
||
paper.r = paper.g = paper.b = 0;
|
||
ink.r = ink.g = ink.b = 255;
|
||
|
||
rect.w = kx, rect.h = ky;
|
||
|
||
/*
|
||
* NEED BOUNDARY CHECK !
|
||
*/
|
||
|
||
for (foo=0; foo<8; foo++) /* 8 scan lines */
|
||
{
|
||
octet = priv_fonte[(code*8)+foo];
|
||
rect.y = (foo * ky) + y;
|
||
for (bar=0; bar<8; bar++)
|
||
{
|
||
rect.x = (bar * kx) + x;
|
||
rect.x = ((8-bar)*kx) + x;
|
||
if (octet & 1)
|
||
{
|
||
Image_paint_rect(im, &rect, 255, 198, 0);
|
||
Image_draw_rect(im, &rect, 0, 0, 80);
|
||
}
|
||
octet >>= 1;
|
||
}
|
||
}
|
||
|
||
im->modified++;
|
||
|
||
return FUNC_IS_BETA;
|
||
}
|
||
/*::------------------------------------------------------------------::*/
|