2b165b | 2001-09-26 | Martin Nilsson | |
|
f41b98 | 2009-05-07 | Martin Stjernholm | |
|
2b165b | 2001-09-26 | Martin Nilsson | |
|
a686be | 2000-09-04 | Per Hedbor | | #include <config.h>
inherit "imagetar";
constant name = "Compact image file font";
constant doc =
#"A compact image file.
The format is very simple:
<pre>
'CIF1' (4 bytes magic)
'fontname' (64 bytes name, \\0 terminated)
for each char:
char (4 bytes charcode)
len (4 bytes image length)
len bytes data
</pre>
All integers are NBO<p>
|
93934d | 2000-09-17 | Martin Nilsson | | There is a small program included in bin (create_cif.pike) that
|
a686be | 2000-09-04 | Per Hedbor | | creates a cif font from an imagedir or imagetar font</p>";
class StringFile
{
string data;
int offset;
string _sprintf()
{
return "StringFile("+strlen(data)+","+offset+")";
}
string read(int nbytes)
{
if(!nbytes)
{
offset = strlen(data);
return data;
}
string d = data[offset..offset+nbytes-1];
offset += strlen(d);
return d;
}
void write(mixed ... args)
{
throw( ({ "File not open for write\n", backtrace() }) );
}
void seek(int to)
{
offset = to;
}
void create(string d)
{
data = d;
}
}
class CIF
{
Stdio.File fd;
array filelist ;
mapping offsets;
|
6c8b73 | 2001-01-03 | Per Hedbor | | string prefix="";
|
a686be | 2000-09-04 | Per Hedbor | | array get_dir( string f )
{
if(!filelist)
{
offsets = ([]);
filelist = ({ "/fontname" });
fd->seek( 64 + 4 );
int c;
while( c = getint() )
{
offsets[c] = fd->tell();
if( c < 48 || c > 127 )
if( c == 0xffffffff )
filelist += ({ "/fontinfo" });
else
filelist += ({ sprintf( "/0x%x", c ) });
else
filelist += ({ sprintf( "/%c", c ) });
|
6c8b73 | 2001-01-03 | Per Hedbor | | if( c == 0xfffffffe )
prefix = fd->read( getint() );
else
fd->read( getint() );
|
a686be | 2000-09-04 | Per Hedbor | | }
}
return filelist;
}
int getint( )
{
int c;
sscanf( fd->read( 4 ), "%4c", c );
return c;
}
object open( string fname, string mode )
{
if(!offsets) get_dir( "foo" );
fname -= "/";
if( fname == "fontname" )
{
fd->seek( 4 );
return StringFile( fd->read( 64 )-"\0" );
}
int wc;
sscanf( fname, "%s.", fname );
if( strlen(fname) > 2 ) sscanf( fname, "0x%x", wc ); else wc=fname[0];
|
6c8b73 | 2001-01-03 | Per Hedbor | | if( fname == "fontinfo" )
wc = 0xffffffff;
|
a686be | 2000-09-04 | Per Hedbor | |
if( offsets[ wc ] )
{
fd->seek( offsets[ wc ] );
|
6c8b73 | 2001-01-03 | Per Hedbor | | if( wc <= 0x7fffffff )
return StringFile( prefix+fd->read( getint() ) );
|
a686be | 2000-09-04 | Per Hedbor | | return StringFile( fd->read( getint() ) );
}
return 0;
}
void create( string fname )
{
fd = Stdio.File( );
if( !fd->open( fname, "r" ) ) error( "Illegal CIF\n");
if( fd->read( 4 ) != "CIF1" ) error( "Illegal CIF\n");
}
}
mapping(string:CIF) cif_cache = ([]);
CIF open_tar( string path )
{
CIF res;
if( cif_cache[ path ] )
return cif_cache[ path ];
if( !catch { res= CIF( path ); } )
cif_cache[ path ] = res;
while( sizeof( cif_cache ) > 10 )
{
array q = indices( cif_cache );
string w = q[ random( sizeof(q) ) ];
if( w != path )
m_delete( cif_cache, w );
}
return open_tar( path );
}
array(mapping) font_information( string fnt )
{
array res = ::font_information( fnt );
if( sizeof( res ) ) res[0]->format = "cif";
return res;
}
void update_font_list()
{
font_list = ([]);
void rec_find_in_dir( string dir )
{
foreach( get_dir( dir )||({}), string pd )
{
|
cf92fe | 2003-09-18 | Martin Stjernholm | | if( Stdio.is_dir( dir+pd ) )
|
a686be | 2000-09-04 | Per Hedbor | | rec_find_in_dir( dir+pd+"/" );
else if( glob( "*.cif", pd ) )
{
CIF t = open_tar( dir+pd );
|
8cd3ad | 2001-02-08 | Martin Nilsson | | if( Stdio.File f = t->open( "fontname", "r" ) ) {
string name = f->read();
if( Stdio.File f = t->open( "fontinfo", "r" ) )
font_list[font_name( "<name>"+name+"</name>"+f->read() )] = dir+pd;
else
font_list[font_name( name )] = dir+pd;
}
|
a686be | 2000-09-04 | Per Hedbor | | else
destruct( t );
}
}
};
foreach(roxen->query("font_dirs"), string dir)
|
45e01b | 2011-12-28 | Martin Stjernholm | | rec_find_in_dir( roxen_path (dir) );
|
a686be | 2000-09-04 | Per Hedbor | | }
|