2b165b2001-09-26Martin Nilsson // This file is part of Roxen WebServer.
f41b982009-05-07Martin Stjernholm // Copyright © 2000 - 2009, Roxen IS.
2b165b2001-09-26Martin Nilsson 
a686be2000-09-04Per 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>
93934d2000-09-17Martin Nilsson There is a small program included in bin (create_cif.pike) that
a686be2000-09-04Per 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;
6c8b732001-01-03Per Hedbor  string prefix="";
a686be2000-09-04Per Hedbor  array get_dir( string f ) { if(!filelist) { offsets = ([]); filelist = ({ "/fontname" }); fd->seek( 64 + 4 ); // header. 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 ) });
6c8b732001-01-03Per Hedbor  if( c == 0xfffffffe ) prefix = fd->read( getint() ); else fd->read( getint() );
a686be2000-09-04Per Hedbor  } } return filelist; } int getint( ) { int c; sscanf( fd->read( 4 ), "%4c", c ); return c; } object open( string fname, string mode ) { // #ifdef THREADS // object lock = lock->trylock(); // #endif if(!offsets) get_dir( "foo" ); fname -= "/"; if( fname == "fontname" ) { fd->seek( 4 ); return StringFile( fd->read( 64 )-"\0" ); } // werror("open "+fname+"\n"); int wc; sscanf( fname, "%s.", fname ); if( strlen(fname) > 2 ) sscanf( fname, "0x%x", wc ); else wc=fname[0];
6c8b732001-01-03Per Hedbor  if( fname == "fontinfo" ) wc = 0xffffffff;
a686be2000-09-04Per Hedbor  if( offsets[ wc ] ) { fd->seek( offsets[ wc ] );
6c8b732001-01-03Per Hedbor  if( wc <= 0x7fffffff ) // Normal character return StringFile( prefix+fd->read( getint() ) );
a686be2000-09-04Per 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 ) {
cf92fe2003-09-18Martin Stjernholm  if( Stdio.is_dir( dir+pd ) )
a686be2000-09-04Per Hedbor  rec_find_in_dir( dir+pd+"/" ); else if( glob( "*.cif", pd ) ) { CIF t = open_tar( dir+pd );
8cd3ad2001-02-08Martin 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; }
a686be2000-09-04Per Hedbor  else destruct( t ); } } }; foreach(roxen->query("font_dirs"), string dir)
45e01b2011-12-28Martin Stjernholm  rec_find_in_dir( roxen_path (dir) );
a686be2000-09-04Per Hedbor }