196 lines
3.8 KiB
C
196 lines
3.8 KiB
C
|
/*
|
||
|
|
||
|
bdf_8x8.c
|
||
|
|
||
|
unencoded font format for 8x8 pixel font
|
||
|
|
||
|
offset bytes desc
|
||
|
0 1 first char
|
||
|
1 1 last char
|
||
|
2 1 horizontal tile count (x), new 2019 format, issue 771
|
||
|
3 1 vertical tile count (y), new 2019 format, issue 771
|
||
|
4 n font data, n = (last char - first char + 1)*8
|
||
|
|
||
|
*/
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <assert.h>
|
||
|
#include "bdf_font.h"
|
||
|
|
||
|
|
||
|
static int bg_8x8_convert(bg_t *bg, bbx_t *bbx, int xo, int yo)
|
||
|
{
|
||
|
int x;
|
||
|
int y;
|
||
|
int d;
|
||
|
|
||
|
if ( bbx == NULL )
|
||
|
bbx = &(bg->bbx);
|
||
|
|
||
|
|
||
|
/*
|
||
|
if ( bbx->w != 8 )
|
||
|
return 0;
|
||
|
if ( bbx->h != 8 )
|
||
|
return 0;
|
||
|
*/
|
||
|
|
||
|
/*
|
||
|
for( y = bbx->y+bbx->h-1; y >= bbx->y; y--)
|
||
|
{
|
||
|
d = 0;
|
||
|
for( x = bbx->x; x < bbx->x + bbx->w; x++)
|
||
|
{
|
||
|
d <<= 1;
|
||
|
if ( bg_GetBBXPixel(bg, x, y) != 0 )
|
||
|
{
|
||
|
d++;
|
||
|
}
|
||
|
}
|
||
|
if ( bg_AddTargetData(bg, d) < 0 )
|
||
|
return 0;
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
for( x = bbx->x; x < bbx->x + bbx->w; x++)
|
||
|
{
|
||
|
d = 0;
|
||
|
for( y = bbx->y+bbx->h-1; y >= bbx->y; y--)
|
||
|
{
|
||
|
d >>= 1;
|
||
|
if ( bg_GetBBXPixel(bg, x+xo, y+yo) != 0 )
|
||
|
{
|
||
|
d |= 128;
|
||
|
}
|
||
|
}
|
||
|
if ( bg_AddTargetData(bg, d) < 0 )
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
|
||
|
void bf_Generate8x8Font(bf_t *bf, int xo, int yo)
|
||
|
{
|
||
|
int i, j, k;
|
||
|
bg_t *bg;
|
||
|
int first, last;
|
||
|
bbx_t local_bbx;
|
||
|
int is_glyph_written;
|
||
|
int x, y;
|
||
|
|
||
|
/* Step 1: Generate 8x8 bitmap data */
|
||
|
|
||
|
for( i = 0; i < bf->glyph_cnt; i++ )
|
||
|
{
|
||
|
bg = bf->glyph_list[i];
|
||
|
if ( bg->map_to >= 0 )
|
||
|
{
|
||
|
bf_copy_bbx_and_update_shift(bf, &local_bbx, bg);
|
||
|
|
||
|
if ( (local_bbx.w & 7) != 0 )
|
||
|
{
|
||
|
bf_Log(bf, "Generate8x8Font: Error, glyph width is not multiple of 8, width=%d, encoding=%d", local_bbx.w, bg->encoding);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ( (local_bbx.h & 7) != 0 )
|
||
|
{
|
||
|
bf_Log(bf, "Generate8x8Font: Error, glyph height is not multiple of 8, height=%d, encoding=%d", local_bbx.h, bg->encoding);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
bg_ClearTargetData(bg);
|
||
|
for( y = 0; y < bf->tile_v_size; y++ )
|
||
|
{
|
||
|
for( x = 0; x < bf->tile_h_size; x++ )
|
||
|
{
|
||
|
//bf_Log(bf, "Generate8x8Font: Encoding %d, x=%d, y=%d", bg->encoding, x, y);
|
||
|
|
||
|
if ( bg_8x8_convert(bg, &local_bbx, xo+8*x, yo+8*(bf->tile_v_size-y-1)) == 0 )
|
||
|
{
|
||
|
bf_Log(bf, "Generate8x8Font: Error, 8x8 conversion, encoding=%d", bg->target_cnt, bg->encoding);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Step 2: Calculate first and last char */
|
||
|
|
||
|
first = -1;
|
||
|
last = -1;
|
||
|
|
||
|
for( j = 0; j < 256; j++ )
|
||
|
{
|
||
|
for( i = 0; i < bf->glyph_cnt; i++ )
|
||
|
{
|
||
|
bg = bf->glyph_list[i];
|
||
|
if ( bg->map_to == j )
|
||
|
{
|
||
|
if ( bg->target_data != NULL )
|
||
|
{
|
||
|
//bf_Log(bf, "Generate8x8Font: Encoding %d, size=%d", bg->encoding, bg->target_cnt);
|
||
|
|
||
|
if ( bg->target_cnt != bf->tile_h_size*bf->tile_v_size*8)
|
||
|
{
|
||
|
bf_Log(bf, "Generate8x8Font: Error, glyph size incorrect, size=%d, encoding=%d", bg->target_cnt, bg->encoding);
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if ( first < 0 )
|
||
|
first = j;
|
||
|
last = j;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Step 3: Write font data */
|
||
|
|
||
|
bf_AddTargetData(bf, first);
|
||
|
bf_AddTargetData(bf, last);
|
||
|
bf_AddTargetData(bf, bf->tile_h_size);
|
||
|
bf_AddTargetData(bf, bf->tile_v_size);
|
||
|
bf_Log(bf, "Generate8x8Font: Tile size width=%d height=%d", bf->tile_h_size, bf->tile_v_size);
|
||
|
|
||
|
|
||
|
for( j = first; j <= last; j++ )
|
||
|
{
|
||
|
is_glyph_written = 0;
|
||
|
for( i = 0; i < bf->glyph_cnt; i++ )
|
||
|
{
|
||
|
bg = bf->glyph_list[i];
|
||
|
if ( bg->map_to == j )
|
||
|
{
|
||
|
if ( bg->target_data != NULL )
|
||
|
{
|
||
|
|
||
|
if ( bg->target_cnt == bf->tile_h_size*bf->tile_v_size*8)
|
||
|
{
|
||
|
for( k = 0; k < bg->target_cnt; k++ )
|
||
|
{
|
||
|
bf_AddTargetData(bf, bg->target_data[k]);
|
||
|
}
|
||
|
is_glyph_written = 1;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
if ( is_glyph_written == 0 )
|
||
|
{
|
||
|
for( k = 0; k < bf->tile_h_size*bf->tile_v_size*8; k++ )
|
||
|
{
|
||
|
bf_AddTargetData(bf, 0);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
bf_Log(bf, "Generate8x8Font: Font size %d", bf->target_cnt);
|
||
|
}
|