Changeset 58


Ignore:
Timestamp:
Jun 26, 2006, 6:09:33 PM (15 years ago)
Author:
Eugene Romanenko
Message:

save fonts information in cache file to avoid rescan (closes #30, #32, #35)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/poppler/fc-emulate-os2/fontconfig/fontconfig.cpp

    r57 r58  
    2424// This file is fontconfig replacement which emulates functions
    2525// used by poppler.
    26  
     26
    2727#define INCL_DOS
    2828#define INCL_WIN
     
    4343
    4444
    45 static map<string,string> *fontmap = NULL;
     45static char *newstrdup( const char *s )
     46{
     47    if ( s == NULL ) {
     48        return NULL;
     49    }
     50    char *temp = new char[ strlen( s ) + 1 ];
     51    strcpy( temp, s );
     52    return temp;
     53}
     54
     55// er_tokens - utility class
     56class er_tokens
     57{
     58    private:
     59        char   separator;
     60        size_t len;
     61        char   *str;
     62        char   *tmp;
     63        size_t curoffs;
     64    public:
     65        er_tokens( const char *s, char sep );
     66        ~er_tokens();
     67        char *nexttoken();
     68};
     69
     70er_tokens::er_tokens( const char *s, char sep )
     71{
     72    separator = sep;
     73    len = strlen( s );
     74    str = new char[ len + 1 ];
     75    strcpy( str , s );
     76    tmp = new char[ len + 1 ];
     77    curoffs = 0;
     78}
     79
     80er_tokens::~er_tokens()
     81{
     82    delete str;
     83    delete tmp;
     84}
     85
     86char *er_tokens::nexttoken()
     87{
     88    if ( curoffs >= len ) {
     89        return NULL;
     90    }
     91
     92    memset( tmp, 0, len + 1 );
     93
     94    if ( str[ curoffs ] == separator ) {
     95        curoffs++;
     96    }
     97    else
     98    {
     99        char *t1 = str + curoffs;
     100        char *t2 = tmp;
     101
     102        while ( ( *t1 != separator ) && ( *t1 != 0 ) ) {
     103            *t2++ = *t1++;
     104            curoffs++;
     105        }
     106        curoffs++;
     107    }
     108
     109    return tmp;
     110}
     111
     112struct FcfRecord
     113{
     114    char filename[ _MAX_PATH ];
     115    char family[ 64 ];
     116    char style[ 64 ];
     117    long size;
     118    long modified;
     119};
     120
     121static map<string,string>    *fontmap = NULL;   // font name / font filename
     122static map<string,FcfRecord> *fcfmap = NULL;    // font filename / FcfRecord
     123static bool fcfChanged = false;
     124static FT_Library ftlib;
    46125
    47126
     
    58137};
    59138
    60 static char *newstrdup( const char *s )
    61 {
    62     if ( s == NULL ) {
    63         return NULL;
    64     }
    65     char *temp = new char[ strlen( s ) + 1 ];
    66     strcpy( temp, s );
    67     return temp;
    68 }
    69 
    70139
    71140FcConfig *FcConfigGetCurrent()
     
    92161    delete s;
    93162}
    94 
    95 
    96 FT_Library ftlib;
    97 
    98163
    99164static void ftLoad( char *fn )
     
    104169    }
    105170
     171    if ( ( stricmp( fn + ( l - 4 ), ".OFM" ) != 0 ) &&
     172         ( stricmp( fn + ( l - 4 ), ".PFB" ) != 0 ) &&
     173         ( stricmp( fn + ( l - 4 ), ".PFA" ) != 0 ) &&
     174         ( stricmp( fn + ( l - 4 ), ".TTF" ) != 0 ) &&
     175         ( stricmp( fn + ( l - 4 ), ".TTC" ) != 0 ) )
     176    {
     177        return;
     178    }
     179
    106180    if ( stricmp( fn + ( l - 4 ), ".OFM" ) == 0 ) {
    107181        fn[ l - 3 ] = 'P';
     
    109183    }
    110184
    111     FT_Face ftface;
    112     if ( FT_New_Face( ftlib, fn, 0, &ftface ) ) {
    113         return;
    114     }
    115 
    116     string key = ftface->family_name;
    117     if ( stricmp( ftface->style_name, "regular" ) != 0 ) {
     185    string familyName = "";
     186    string styleName = "";
     187
     188    bool needread = false;
     189    struct stat st = {0};
     190    stat( fn, &st );
     191
     192    if ( fcfmap->find( fn ) == fcfmap->end() ) {
     193        needread = true;
     194    }
     195    else {
     196        FcfRecord r = (*fcfmap)[ fn ];
     197        if ( ( r.size == st.st_size ) && ( r.modified == st.st_mtime ) ) {
     198            familyName = r.family;
     199            styleName = r.style;
     200        }
     201        else {
     202            needread = true;
     203        }
     204    }
     205
     206    if ( needread )
     207    {
     208        //printf( "read: %s\n", fn );
     209        fcfChanged = true;
     210
     211        FT_Face ftface;
     212        if ( FT_New_Face( ftlib, fn, 0, &ftface ) ) {
     213            return;
     214        }
     215
     216        familyName = ftface->family_name;
     217        styleName = ftface->style_name;
     218
     219        FT_Done_Face( ftface );
     220    }
     221
     222    string key = familyName;
     223    if ( stricmp( styleName.c_str(), "regular" ) != 0 ) {
    118224        key += ' ';
    119         key += ftface->style_name;
     225        key += styleName;
    120226    }
    121227
     
    128234    //printf( "%s: %s\n", fn, key.c_str() );
    129235
    130     FT_Done_Face( ftface );
    131 }
    132 
    133 
    134 static void loadDir( string path )
     236    FcfRecord fcfr = {0};
     237    strcpy( fcfr.filename, fn );
     238    strncpy( fcfr.family, familyName.c_str(), sizeof( fcfr.family ) - 1 );
     239    strncpy( fcfr.style, styleName.c_str(), sizeof( fcfr.style ) - 1 );
     240    fcfr.size = st.st_size;
     241    fcfr.modified = st.st_mtime;
     242
     243    (*fcfmap)[ fn ] = fcfr;
     244}
     245
     246
     247static string getFcfName()
     248{
     249    char fullpath[ _MAX_PATH ];
     250    char drive[ _MAX_DRIVE ];
     251    char dir[ _MAX_DIR ];
     252    char fname[ _MAX_FNAME ];
     253    _splitpath( __argv[0], drive, dir, fname, NULL );
     254    strlwr( fname );
     255    _makepath( fullpath, drive, dir, fname, ".fcf" );
     256    return fullpath;
     257}
     258
     259/*static void loadDir( string path )
    135260{
    136261    string pathnam = path + "\\*";
     
    147272    }
    148273    _dos_findclose( &ffblk );
    149 }
    150 
     274} */
     275
     276static void saveFcf( const char *fn )
     277{
     278    FILE *f = NULL;
     279
     280    if ( ( f = fopen( fn, "w" ) ) == NULL ) {
     281        return;
     282    }
     283
     284    fputs( "# Font configuration file.\n" \
     285           "# Auto-generated file, do not edit!\n", f );
     286
     287    map<string,FcfRecord>::const_iterator iter;
     288    for ( iter = fcfmap->begin(); iter != fcfmap->end(); iter++ )
     289    {
     290        FcfRecord r = (*iter).second;
     291        fprintf( f, "|%s|%s|%s|%ld|%ld|\n", r.filename, r.family, r.style,
     292                 r.size, r.modified );
     293    }
     294    fclose( f );
     295}
     296
     297#define READ_BUF    4096
     298static void readFcf( const char *fn )
     299{
     300    if ( access( fn, 0 ) != 0 ) {
     301        return;
     302    }
     303
     304    FILE *f = NULL;
     305
     306    if ( ( f = fopen( fn, "r" ) ) == NULL ) {
     307        return;
     308    }
     309
     310    char *buf = new char[ READ_BUF ];
     311
     312    while( fgets( buf, READ_BUF, f ) != NULL )
     313    {
     314        if ( buf[0] == '|' )
     315        {
     316            FcfRecord r = {0};
     317
     318            er_tokens tkn( buf + 1, '|' );
     319            strncpy( r.filename, tkn.nexttoken(), sizeof( r.filename ) - 1 );
     320            strncpy( r.family, tkn.nexttoken(), sizeof( r.family ) - 1 );
     321            strncpy( r.style, tkn.nexttoken(), sizeof( r.style ) - 1 );
     322            r.size = atol( tkn.nexttoken() );
     323            r.modified = atol( tkn.nexttoken() );
     324
     325            (*fcfmap)[ r.filename ] = r;
     326        }
     327    }
     328
     329    fclose( f );
     330}
    151331
    152332#define FLIST_SIZE  (1024*64)
    153333
    154 //
    155 // TODO: save fonts information in cache file to avoid rescan
    156 //       if no fonts added
    157 //
     334
    158335FcBool FcInit()
    159336{
     
    166343    }
    167344
     345    fcfChanged = false;
     346
     347    string fcfname = getFcfName();
     348
    168349    fontmap = new map<string,string>;
     350    fcfmap  = new map<string,FcfRecord>;
     351
     352    readFcf( fcfname.c_str() );
    169353
    170354    // enum installed fonts
     
    183367    while ( fnames[ noffset ] != 0 )
    184368    {
    185 
    186369        const char *fname = fnames + noffset;
    187370
     
    207390
    208391    // TODO: load some fonts dir?
    209     //loadDir( "C:\\Programs\\AcrobatReader\\Adobe\\Acrobat 4.0\\Resource\\Font" );
     392    //loadDir( "Fonts" );
     393
     394    if ( fcfChanged ) {
     395        saveFcf( fcfname.c_str() );
     396    }
    210397
    211398    return FcTrue;
     
    215402//
    216403// Assume fonts "Times New Roman", "Helvetica" and "Courier" always
    217 // present on any system (see GPI Guide and Reference, section 
     404// present on any system (see GPI Guide and Reference, section
    218405// "Fonts" -> "About Fonts" -> "PM-Supplied Fonts").
    219 // 
     406//
    220407#define DEFAULT_SERIF_FONT          "times new roman"
    221408#define DEFAULT_SANSSERIF_FONT      "helvetica"
     
    279466    }
    280467
    281     printf( "MATCHED STYLE: %s, FILENAME: %s\n", key.c_str(), pat->filename );
     468    //printf( "MATCHED STYLE: %s, FILENAME: %s\n", key.c_str(), pat->filename );
    282469
    283470    FcFontSet *fs = new FcFontSet;
     
    324511                    const char *fcLang, FcType tLang, const char *lang, void * )
    325512{
    326     printf( "FAMILY: %s, SLANT: %d, WEIGHT: %d, WIDTH: %d, SPACING: %d, LANG: %s\n",
    327             family, slant, weight, width, spacing, lang );
     513    //printf( "FAMILY: %s, SLANT: %d, WEIGHT: %d, WIDTH: %d, SPACING: %d, LANG: %s\n",
     514    //        family, slant, weight, width, spacing, lang );
    328515
    329516    FcPattern *p = new FcPattern;
Note: See TracChangeset for help on using the changeset viewer.