/*! \brief Adds the FontFamily/FontStyle that is represented by this path. */ status_t FontManager::_AddFont(font_directory& directory, BEntry& entry) { node_ref nodeRef; status_t status = entry.GetNodeRef(&nodeRef); if (status < B_OK) return status; BPath path; status = entry.GetPath(&path); if (status < B_OK) return status; FT_Face face; FT_Error error = FT_New_Face(gFreeTypeLibrary, path.Path(), 0, &face); if (error != 0) return B_ERROR; FontFamily *family = _FindFamily(face->family_name); if (family != NULL && family->HasStyle(face->style_name)) { // prevent adding the same style twice // (this indicates a problem with the installed fonts maybe?) FT_Done_Face(face); return B_OK; } if (family == NULL) { family = new (std::nothrow) FontFamily(face->family_name, fNextID++); if (family == NULL || !fFamilies.BinaryInsert(family, compare_font_families)) { delete family; FT_Done_Face(face); return B_NO_MEMORY; } } FTRACE(("\tadd style: %s, %s\n", face->family_name, face->style_name)); // the FontStyle takes over ownership of the FT_Face object FontStyle *style = new FontStyle(nodeRef, path.Path(), face); if (!family->AddStyle(style)) { delete style; delete family; return B_NO_MEMORY; } directory.styles.AddItem(style); fStyleHashTable.AddItem(style); if (directory.AlreadyScanned()) directory.revision++; 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; }