/*! \brief Scan a folder for all valid fonts \param directoryPath Path of the folder to scan. */ status_t FontManager::_ScanFontDirectory(font_directory& fontDirectory) { // This bad boy does all the real work. It loads each entry in the // directory. If a valid font file, it adds both the family and the style. BDirectory directory; status_t status = directory.SetTo(&fontDirectory.directory); if (status != B_OK) return status; BEntry entry; while (directory.GetNextEntry(&entry) == B_OK) { if (entry.IsDirectory()) { // scan this directory recursively font_directory* newDirectory; if (_AddPath(entry, &newDirectory) == B_OK && newDirectory != NULL) _ScanFontDirectory(*newDirectory); continue; } // TODO: Commenting this out makes my "Unicode glyph lookup" // work with our default fonts. The real fix is to select the // Unicode char map (if supported), and/or adjust the // utf8 -> glyph-index mapping everywhere to handle other // char maps. We could also ignore fonts that don't support // the Unicode lookup as a temporary "solution". #if 0 FT_CharMap charmap = _GetSupportedCharmap(face); if (!charmap) { FT_Done_Face(face); continue; } face->charmap = charmap; #endif _AddFont(fontDirectory, entry); // takes over ownership of the FT_Face object } fontDirectory.revision = 1; return B_OK; }
/*! \brief Scan a folder for all valid fonts \param fontspath Path of the folder to scan. \return - \c B_OK Success - \c B_NAME_TOO_LONG The path specified is too long - \c B_ENTRY_NOT_FOUND The path does not exist - \c B_LINK_LIMIT A cyclic loop was detected in the file system - \c B_BAD_VALUE Invalid input specified - \c B_NO_MEMORY Insufficient memory to open the folder for reading - \c B_BUSY A busy node could not be accessed - \c B_FILE_ERROR An invalid file prevented the operation. - \c B_NO_MORE_FDS All file descriptors are in use (too many open files). */ status_t FontServer::ScanDirectory(const char *fontspath) { // This bad boy does all the real work. It loads each entry in the // directory. If a valid font file, it adds both the family and the style. // Both family and style are stored internally as BStrings. Once everything int32 validcount=0; FT_Face face; FT_Error error; FT_CharMap charmap; FontFamily *family; DIR* hDir; dirent* psEntry; printf( "FontServer::ScanDirectory(): opening %s\n", fontspath ); if ( (hDir = opendir( fontspath ) ) ) { while( (psEntry = readdir( hDir )) ) { printf( "FontServer::ScanDirectory(): found entry %s\n", psEntry->d_name ); char zFullPath[ PATH_MAX ]; if ( strcmp( psEntry->d_name, "." ) == 0 || strcmp( psEntry->d_name, ".." ) == 0 ) { continue; } strcpy( zFullPath, fontspath ); pathcat( zFullPath, psEntry->d_name ); error=FT_New_Face(ftlib, zFullPath,0,&face); if (error!=0) continue; charmap=_GetSupportedCharmap(face); if(!charmap) { FT_Done_Face(face); continue; } face->charmap=charmap; family=_FindFamily(face->family_name ); if (!family) { #ifdef PRINT_FONT_LIST printf("Font Family: %s\n",face->family_name); #endif family=new FontFamily(face->family_name); families->AddItem(family); } if(family->HasStyle(face->style_name)) { FT_Done_Face(face); continue; } #ifdef PRINT_FONT_LIST printf("\tFont Style: %s\n",face->style_name); #endif // Has vertical metrics? family->AddStyle(zFullPath,face); validcount++; FT_Done_Face(face); } printf( "Directory '%s' scanned, %ld fonts found\n", fontspath, validcount ); closedir( hDir ); } need_update=true; return B_OK; }