/*! \brief Removes a font family from the font list \param family The family to remove */ void FontServer::RemoveFamily(const char *family) { FontFamily *f=_FindFamily(family); if(f) { families->RemoveItem(f); delete f; } }
/*! \brief Counts the number of styles available in a font family \param family Name of the font family to scan \return The number of font styles currently available for the font family */ int32 FontServer::CountStyles(const char *family) { FontFamily *f=_FindFamily(family); if(f) { return f->CountStyles(); } return 0; }
/*! \brief Retrieves the FontStyle object \param family The font's family \param face The font's style \return The FontStyle having those attributes or NULL if not available */ FontStyle *FontServer::GetStyle(font_family family, font_style face) { FontFamily *ffam=_FindFamily(family); if(ffam) { FontStyle *fsty=ffam->GetStyle(face); return fsty; } return NULL; }
/*! \brief Locates a FontFamily object by name \param name The family to find \return Pointer to the specified family or NULL if not found. */ FontFamily* FontManager::GetFamily(const char* name) { if (name == NULL) return NULL; FontFamily* family = _FindFamily(name); if (family != NULL) return family; if (fScanned) return NULL; // try font mappings before failing if (_AddMappedFont(name) == B_OK) return _FindFamily(name); _ScanFonts(); return _FindFamily(name); }
/*! \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 Sets the system's fixed font to the specified family and style \param family Name of the font's family \param style Name of the style desired \param size Size desired \return true if successful, false if not. */ bool FontServer::SetSystemFixed(const char *family, const char *style, float size) { FontFamily *fam=_FindFamily(family); if(!fam) return false; FontStyle *sty=fam->GetStyle(style); if(!sty) return false; if(fixed) delete fixed; fixed=sty->Instantiate(size); return true; }
/*! \brief Sets the system's plain font to the specified family and style \param family Name of the font's family \param style Name of the style desired \param size Size desired \return true if successful, false if not. */ bool FontServer::SetSystemPlain(const char *family, const char *style, float size) { FontFamily *fam=_FindFamily(family); if(!fam) return false; FontStyle *sty=fam->GetStyle(style); if(!sty) return false; if(plain) delete plain; plain=sty->Instantiate(size); return true; }
/*! \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; }