38d097 | 2000-09-04 | Per Hedbor | | #include <config.h>
#include <stat.h>
|
3c607d | 2001-01-01 | Martin Nilsson | | constant cvs_version = "$Id: imagedir.pike,v 1.7 2000/12/31 23:54:53 nilsson Exp $";
|
38d097 | 2000-09-04 | Per Hedbor | |
constant name = "Image directory fonts";
constant doc = ("Handles a directory with images (in almost any format), each "
|
e89226 | 2000-09-04 | Per Hedbor | | "named after the character they will represent. Characters "
"with codes larger than 127 or less than 48 are encoded like "
|
0bd4d9 | 2000-09-04 | Per Hedbor | | "0xHEX where HEX is the code in hexadecimal. There must be a "
"file named 'fontname' in the directory, the first line of "
"that file is used as the name of the font");
|
38d097 | 2000-09-04 | Per Hedbor | |
inherit FontHandler;
|
e89226 | 2000-09-04 | Per Hedbor | | #ifdef THREADS
Thread.Mutex lock = Thread.Mutex();
#endif
|
b5aa9c | 2000-09-04 | Per Hedbor | | static mapping nullchar = ([ "image":Image.Image(1,1),
"alpha":Image.Image(1,1) ]);
static mapping spacechar = ([ "image":Image.Image(10,1),
"alpha":Image.Image(10,1) ]);
static mapping smallspacechar = ([ "image":Image.Image(2,1),
"alpha":Image.Image(2,1) ]);
|
38d097 | 2000-09-04 | Per Hedbor | | class myFont
{
inherit Font;
static string path;
static int size, rsize;
static array files;
static string _sprintf()
{
return sprintf( "FontDir(%O,%d)", path, height() );
}
static string encode_char( string c )
{
|
e89226 | 2000-09-04 | Per Hedbor | | int cc = c[0];
if( (cc < 48) || (cc > 127) ) return sprintf( "0x%x", cc );
return c;
|
38d097 | 2000-09-04 | Per Hedbor | | }
static mapping(string:Image.Image) load_char( string c )
{
|
b5aa9c | 2000-09-04 | Per Hedbor | | if( c[0] == 0x120 ) return smallspacechar;
|
38d097 | 2000-09-04 | Per Hedbor | | if(!files)
files = get_dir( path ) - ({ "fontname" });
|
e89226 | 2000-09-04 | Per Hedbor | | array possible = ({ encode_char(c) })+
glob(encode_char( c )+".*", files);
sort( map(possible,strlen), possible );
|
3efbc9 | 2000-09-16 | Per Hedbor | | catch {
foreach( possible, string pf )
if( mapping r = Image._load( path+pf ) )
return r;
};
|
b5aa9c | 2000-09-04 | Per Hedbor | | if( c == " " ) return spacechar;
|
38d097 | 2000-09-04 | Per Hedbor | | return nullchar;
}
mapping(string:mapping(string:Image.Image)) char_cache = ([]);
static mapping(string:Image.Image) write_char( string c )
{
if( char_cache[ c ] ) return char_cache[ c ];
return char_cache[ c ] = load_char( c );
}
static Image.Image write_row( string text )
{
array(mapping(string:Image.Image)) res = map( text/"", write_char );
|
3c607d | 2001-01-01 | Martin Nilsson | | Image.Image rr;
if(floatp(x_spacing))
rr=Image.Image((int)abs(`+(0,@res->image->xsize())*x_spacing),
max(0,@res->image->ysize()));
else
rr=Image.Image(abs(`+(0,@res->image->xsize())+(sizeof(res)*x_spacing)),
max(0,@res->image->ysize()));
|
38d097 | 2000-09-04 | Per Hedbor | |
float start;
if( x_spacing < 0 ) start = (float)rr->xsize()-res[0]->image->xsize();
foreach( res, mapping(string:Image.Image) r )
{
if( !r->image ) continue;
if( r->alpha )
rr->paste_mask(r->image,r->alpha,
(int)start,rr->ysize()-r->image->ysize() );
else
rr->paste(r->image,(int)start,rr->ysize()-r->image->ysize());
|
3c607d | 2001-01-01 | Martin Nilsson | | if(floatp(x_spacing))
start += r->image->xsize()*x_spacing;
else
start += r->image->xsize()+x_spacing;
|
38d097 | 2000-09-04 | Per Hedbor | | }
return rr;
}
int height()
{
return rsize ? rsize : (rsize = text_extents("0WjI|9")[1] );
}
Image.Image write( string ... what )
{
array(Image.Image) res = map( what, write_row );
|
3c607d | 2001-01-01 | Martin Nilsson | | Image.Image rr;
if(floatp(y_spacing))
rr = Image.Image( max(0,@res->xsize()),
(int)abs(`+(0,@res->ysize())*y_spacing) );
else
rr = Image.Image( max(0,@res->xsize()),
abs(`+(0,@res->ysize())+(sizeof(res)+y_spacing)) );
|
38d097 | 2000-09-04 | Per Hedbor | |
float start;
if( y_spacing < 0 ) start = (float)rr->ysize()-res[0]->ysize();
foreach( res, object r )
{
if( j_right ) rr->paste(r,rr->xsize()-r->xsize(),(int)start);
else if( j_center ) rr->paste(r,(rr->xsize()-r->xsize())/2,(int)start);
else rr->paste( r, 0, (int)start );
|
3c607d | 2001-01-01 | Martin Nilsson | | if(floatp(y_spacing))
start += r->ysize()*y_spacing;
else
start += r->ysize()+y_spacing;
|
38d097 | 2000-09-04 | Per Hedbor | | }
return rr;
}
array text_extents( string what )
{
Image.Image o = write( what );
return ({ o->xsize(), o->ysize() });
}
void create( string _path, int _size )
{
path = _path;
size = _size;
}
}
mapping font_list;
|
fad0b7 | 2000-09-16 | Martin Nilsson | | mapping meta_data;
|
38d097 | 2000-09-04 | Per Hedbor | | static string font_name( string what )
{
|
fad0b7 | 2000-09-16 | Martin Nilsson | | if(!meta_data) meta_data=([]);
mapping _meta_data=([]);
Parser.HTML()->
add_containers( ([ "name":lambda(string t, mapping m, string c) {
what=c; return ""; },
"meta":lambda(string t, mapping m, string c) {
_meta_data[m->name]=c; },
]) )->finish(what);
what=(lower_case( replace(what," ","_") )/"\n")[0]-"\r";
if(sizeof(_meta_data)) meta_data[what]=_meta_data;
return what;
|
38d097 | 2000-09-04 | Per Hedbor | | }
void update_font_list()
{
font_list = ([]);
foreach(roxen->query("font_dirs"), string dir)
foreach( (get_dir( dir )||({})), string d )
if( file_stat( dir+d )[ ST_SIZE ] == -2 )
if( file_stat( dir+d+"/fontname" ) )
font_list[font_name(Stdio.read_bytes(dir+d+"/fontname"))]=dir+d+"/";
}
array available_fonts()
{
|
e89226 | 2000-09-04 | Per Hedbor | | #ifdef THREADS
object key = lock->lock();
#endif
|
38d097 | 2000-09-04 | Per Hedbor | | array res = ({});
if( !font_list ) update_font_list();
return indices( font_list );
}
array(mapping) font_information( string fnt )
{
|
e89226 | 2000-09-04 | Per Hedbor | | #ifdef THREADS
object key = lock->lock();
#endif
|
38d097 | 2000-09-04 | Per Hedbor | | if( !font_list ) update_font_list();
if( font_list[ fnt ] )
|
fad0b7 | 2000-09-16 | Martin Nilsson | | return ({ (meta_data[fnt] || ([])) | ([
|
38d097 | 2000-09-04 | Per Hedbor | | "name":fnt,
"family":fnt,
"path":font_list[fnt],
"format":"imagedir",
])
});
return ({});
}
array has_font( string name, int size )
{
|
e89226 | 2000-09-04 | Per Hedbor | | #ifdef THREADS
object key = lock->lock();
#endif
|
38d097 | 2000-09-04 | Per Hedbor | | if( !font_list ) update_font_list();
if( font_list[ name ] )
return ({ "nn" });
}
Font open( string name, int size, int bold, int italic )
{
|
e89226 | 2000-09-04 | Per Hedbor | | #ifdef THREADS
object key = lock->lock();
#endif
|
38d097 | 2000-09-04 | Per Hedbor | | if( !font_list ) update_font_list();
if( font_list[ name ] )
return myFont( font_list[name], size );
}
void create()
{
roxen.getvar( "font_dirs" )
->add_changed_callback( lambda(Variable.Variable v){
font_list = 0;
} );
}
|