On Friday 14 December 2001 13:56, Steve Swales wrote:
> But every glyph would have to be sent over the wire as a pixmap, every time
> it's drawn. Performance would be so bad, particularly over the wire, that
> it would be as good as broken... or am I missing something?
Well, perhaps glyph compression might help.
Keith, if you remember I proposed you on ALS to RLE compress glyphs for
sending over the wire. Since this came up again, I just wanted to attach some
code that I use in libAfterImage for antialiased glyph compression. It yelds
from 1:5 to 1:10 compression ratio in most cases.
Basically it is function that takes FreeType (or the likes) generated 8bpp
pixmap as src, and generates RLE encoded block. Note that src_step is offset
between rows of the original pixmap, and for FreeType generated glyphs its
bmap->pitch.
Please let me know if you have any questions.
>
> -steve
>
Sasha Vasko
static unsigned char *
compress_glyph_pixmap( unsigned char *src, unsigned char *buffer,
unsigned int width, unsigned int height,
int src_step )
{
unsigned char *pixmap ;
register unsigned char *dst = buffer ;
register int k = 0, i = 0 ;
int count = -1;
unsigned char last = src[0];
/* new way: if its FF we encode it as 01rrrrrr where rrrrrr is repetition count
* if its 0 we encode it as 00rrrrrr. Any other symbol we bitshift right by 1
* and then store it as 1sssssss where sssssss are topmost sugnificant bits.
* Note - single FFs and 00s are encoded as any other character. Its been noted
* that in 99% of cases 0 or FF repeats, and very seldom anything else repeats
*/
while ( height)
{
if( src[k] != last || (last != 0 && last != 0xFF) || count >= 63 )
{
if( count == 0 )
dst[i++] = (last>>1)|0x80;
else if( count > 0 )
{
if( last == 0xFF )
count |= 0x40 ;
dst[i++] = count;
count = 0 ;
}else
count = 0 ;
last = src[k] ;
}else
count++ ;
/*fprintf( stderr, "%2.2X ", src[k] ); */
if( ++k >= width )
{
/* fputc( '\n', stderr ); */
--height ;
k = 0 ;
src += src_step ;
}
}
if( count == 0 )
dst[i++] = (last>>1)|0x80;
else
{
if( last == 0xFF )
count |= 0x40 ;
dst[i++] = count;
}
pixmap = safemalloc( i );
memcpy( pixmap, buffer, i );
return pixmap;
}