Roxen.git/server/font_handlers/ttf.pike:1:
// This file is part of Roxen WebServer.
// Copyright © 1996 - 2000, Roxen IS.
#if !constant(Image.FreeType.Face)
#if constant(has_Image_TTF)
#include <config.h>
- constant cvs_version = "$Id: ttf.pike,v 1.10 2001/09/27 21:51:23 per Exp $";
+ constant cvs_version = "$Id: ttf.pike,v 1.11 2001/11/14 13:36:09 grubba Exp $";
constant name = "TTF fonts";
constant doc = "True Type font loader. Uses freetype to render text.";
constant scalable = 1;
inherit FontHandler;
static mapping ttf_font_names_cache;
static string trimttfname( string n )
Roxen.git/server/font_handlers/ttf.pike:35: Inside #if !constant(Image.FreeType.Face)
case "lightitalic":case "italiclight":return "li";
}
if(search(lower_case(style), "oblique"))
return "ni"; // for now.
return "nn";
}
static void build_font_names_cache( )
{
mapping ttf_done = ([ ]);
- ttf_font_names_cache=([]);
+ mapping new_ttf_font_names_cache=([]);
void traverse_font_dir( string dir )
{
foreach(r_get_dir( dir )||({}), string fname)
{
string path=combine_path(dir+"/",fname);
if(!ttf_done[path]++)
{
Stat a=file_stat(path);
if(a && a[1]==-2) {
if( !file_stat( path+"/fontname" ) )
Roxen.git/server/font_handlers/ttf.pike:59: Inside #if !constant(Image.FreeType.Face)
}
// Here is a good place to impose the artificial restraint that
// the file must match *.ttf
Image.TTF ttf;
if(catch(ttf = Image.TTF( combine_path(dir+"/",fname) )))
continue;
if(ttf)
{
mapping n = ttf->names();
string f = lower_case(trimttfname(n->family));
- if(!ttf_font_names_cache[f])
- ttf_font_names_cache[f] = ([]);
- ttf_font_names_cache[f][ translate_ttf_style(n->style) ]
- = combine_path(dir+"/",fname);
+ if(!new_ttf_font_names_cache[f])
+ new_ttf_font_names_cache[f] = ([]);
+ new_ttf_font_names_cache[f][ translate_ttf_style(n->style) ] =
+ combine_path(dir+"/",fname);
}
}
}
};
map( roxen->query("font_dirs"), traverse_font_dir );
-
+
+ ttf_font_names_cache = new_ttf_font_names_cache;
}
class TTFWrapper
{
inherit Font;
static int size, rsize;
static object real;
static object encoder;
Roxen.git/server/font_handlers/ttf.pike:179: Inside #if !constant(Image.FreeType.Face)
encoder = Locale.Charset.encoder(encoding, "");
real_write = (encoder? write_encoded : real->write);
}
}
#ifdef THREADS
Thread.Mutex lock = Thread.Mutex();
#endif
- array available_fonts()
+ array available_fonts(int(0..1)|void force_reload)
{
#ifdef THREADS
object key = lock->lock();
#endif
- if( !ttf_font_names_cache ) build_font_names_cache( );
+ if( !ttf_font_names_cache || force_reload ) build_font_names_cache( );
return indices( ttf_font_names_cache );
}
array(mapping) font_information( string font )
{
if( !has_font( font, 0 ) )
return ({});
mapping res = ([
"name":font,
Roxen.git/server/font_handlers/ttf.pike:208: Inside #if !constant(Image.FreeType.Face)
if( font[0] == '/' )
f = Image.TTF( font );
else
f = Image.TTF( (font=values(ttf_font_names_cache[ font ])[0]) );
res->path = font;
res |= f->names();
return ({ res });
}
- array(string) has_font( string name, int size )
+ array(string) has_font( string name, int size, int(0..1) force )
{
#ifdef THREADS
object key = lock->lock();
#endif
if( !ttf_font_names_cache )
build_font_names_cache( );
if( ttf_font_names_cache[ name ] )
return indices(ttf_font_names_cache[ name ]);
-
+ if (force) {
+ build_font_names_cache();
+ if( ttf_font_names_cache[ name ] )
+ return indices(ttf_font_names_cache[ name ]);
}
-
+ }
Font open(string f, int size, int bold, int italic )
{
string tmp;
int|string style = font_style( f, size, bold, italic );
object fo;
if( style == -1 ) // exact file
{
if( fo = Image.TTF( name ) )
return TTFWrapper( fo, size, f,0,0 );
return 0;
}
-
+ if (!ttf_font_names_cache) {
+ build_font_names_cache();
+ }
+
if(ttf_font_names_cache[ lower_case(f) ])
{
f = lower_case(f);
if( tmp = ttf_font_names_cache[ f ][ style ] )
{
fo = Image.TTF( tmp );
if( fo ) return TTFWrapper( fo(), size, tmp,0,0 );
}
if( fo = Image.TTF( roxen_path(f = values(ttf_font_names_cache[ f ])[0])))
return TTFWrapper( fo(), size, f, bold, italic );