diff --git a/src/servers/app/server/FontServer.cpp b/src/servers/app/server/FontServer.cpp new file mode 100644 index 0000000000..eb9d78da56 --- /dev/null +++ b/src/servers/app/server/FontServer.cpp @@ -0,0 +1,411 @@ +//------------------------------------------------------------------------------ +// Copyright (c) 2001-2002, OpenBeOS +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// File Name: FontServer.cpp +// Author: DarkWyrm +// Description: Handles the largest part of the font subsystem +// +//------------------------------------------------------------------------------ +#include +#include +#include +#include +#include +#include +#include + +#include "FontFamily.h" +#include "FontServer.h" +#include "ServerFont.h" +#include "ServerConfig.h" + +FTC_Manager ftmanager; +FT_Library ftlib; +FontServer *fontserver; + +static FT_Error face_requester(FTC_FaceID face_id, FT_Library library, + FT_Pointer request_data, FT_Face *aface) +{ + CachedFace face = (CachedFace) face_id; + return FT_New_Face(ftlib,face->file_path.String(),face->face_index,aface); +} + + +FontServer::FontServer(void) +{ + lock=create_sem(1,"fontserver_lock"); + init=(FT_Init_FreeType(&ftlib)==0)?true:false; + +/* + Fire up the font caching subsystem. + The three zeros tell FreeType to use the defaults, which are 2 faces, + 4 face sizes, and a maximum of 200000 bytes. I will probably change + these numbers in the future to maximize performance for your "average" + application. +*/ + if(FTC_Manager_New(ftlib,0,0,0,&face_requester,NULL,&ftmanager)!=0 + && init) + init=false; + + families=new BList(0); + plain=NULL; + bold=NULL; + fixed=NULL; +} + +FontServer::~FontServer(void) +{ + delete_sem(lock); + delete families; + FTC_Manager_Done(ftmanager); + FT_Done_FreeType(ftlib); +} + +void FontServer::Lock(void) +{ + acquire_sem(lock); +} + +void FontServer::Unlock(void) +{ + release_sem(lock); +} + +int32 FontServer::CountFamilies(void) +{ + if(init) + return families->CountItems(); + return 0; +} + +int32 FontServer::CountStyles(const char *family) +{ + FontFamily *f=_FindFamily(family); + if(f) + { + return f->CountStyles(); + } + return 0; +} + +void FontServer::RemoveFamily(const char *family) +{ + FontFamily *f=_FindFamily(family); + if(f) + { + families->RemoveItem(f); + delete f; + } +} + +FontFamily *FontServer::_FindFamily(const char *name) +{ + if(!init) + return NULL; + int32 count=families->CountItems(), i; + FontFamily *family; + for(i=0; iItemAt(i); + if(strcmp(family->Name(),name)==0) + return family; + } + return NULL; +} + +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 + +#ifdef DEBUG_SCANDIR +printf("FontServer::ScanDirectory(%s)\n",fontspath); +#endif + BDirectory dir; + BEntry entry; + BPath path; + entry_ref ref; + status_t stat; + int32 refcount,i, validcount=0; + FT_Face face; + FT_Error error; + FT_CharMap charmap; + FontFamily *family; +// int32 familycount; + + stat=dir.SetTo(fontspath); + if(stat!=B_OK) + return stat; + + refcount=dir.CountEntries(); + + for(i=0;icharmap=charmap; + + family=_FindFamily(face->family_name); + + if(!family) + { + family=new FontFamily(face->family_name); + families->AddItem(family); + } + + if(family->HasStyle(face->style_name)) + { + FT_Done_Face(face); + continue; + } + + // Has vertical metrics? + family->AddStyle(path.Path(),face); + validcount++; + + FT_Done_Face(face); + } // end for(inum_charmaps; i++) + { + charmap=face->charmaps[i]; + switch(charmap->platform_id) + { + case 3: + { + // if Windows Symbol or Windows Unicode + if(charmap->encoding_id==0 || charmap->encoding_id==1) + return charmap; + break; + } + case 1: + { + // if Apple Unicode + if(charmap->encoding_id==0) + return charmap; + break; + } + case 0: + { + // if Apple Roman + if(charmap->encoding_id==0) + return charmap; + break; + } + default: + { + break; + } + } + } + return NULL; + +} + +/* +This saves all family names and styles to the file +/boot/home/config/app_server/fontlist as a flattened BMessage + +This operation is not done very often because the access to disk adds a significant +performance hit. + +The format for storage consists of two things: an array of strings with the name 'family' +and a number of small string arrays which have the name of the font family. These are +the style lists. + +Additionally, any fonts which have bitmap strikes contained in them or any fonts which +are fixed-width are named in the arrays 'tuned' and 'fixed' + +*/ +void FontServer::SaveList(void) +{ + int32 famcount=0, stycount=0,i=0,j=0; + FontFamily *fam; + FontStyle *sty; + BMessage fontmsg, familymsg('FONT'); + BString famname, styname, extraname; + bool fixed,tuned; + + famcount=families->CountItems(); + for(i=0; iItemAt(i); + fixed=false; + tuned=false; + if(!fam) + continue; + + famname=fam->Name(); + + // Add the family to the message + familymsg.AddString("name",famname); + + stycount=fam->CountStyles(); + for(j=0;jGetStyle(j)); + if(styname.CountChars()>0) + { + // Add to list + familymsg.AddString("styles", styname); + + // Check to see if it has prerendered strikes (has "tuned" fonts) + sty=fam->GetStyle(styname.String()); + if(!sty) + continue; + + if(sty->HasTuned() && sty->IsScalable()) + tuned=true; + + // Check to see if it is fixed-width + if(sty->IsFixedWidth()) + fixed=true; + } + } + if(tuned) + familymsg.AddBool("tuned",true); + if(fixed) + familymsg.AddBool("fixed",true); + + fontmsg.AddMessage("family",&familymsg); + familymsg.MakeEmpty(); + } + + BFile file(SERVER_FONT_LIST,B_READ_WRITE | B_CREATE_FILE | B_ERASE_FILE); + if(file.InitCheck()==B_OK) + fontmsg.Flatten(&file); +} + +FontStyle *FontServer::GetStyle(font_family family, font_style face) +{ + FontFamily *ffam=_FindFamily(family); + + if(ffam) + { + FontStyle *fsty=ffam->GetStyle(face); + return fsty; + } + return NULL; +} + +ServerFont *FontServer::GetSystemPlain(void) +{ + if(plain) + { + ServerFont *f=new ServerFont(*plain); + return f; + } + return NULL; +} + +ServerFont *FontServer::GetSystemBold(void) +{ + if(bold) + { + ServerFont *f=new ServerFont(*bold); + return f; + } + return NULL; +} + +ServerFont *FontServer::GetSystemFixed(void) +{ + if(fixed) + { + ServerFont *f=new ServerFont(*fixed); + return f; + } + return NULL; +} + +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; +} + +bool FontServer::SetSystemBold(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(bold) + delete bold; + bold=sty->Instantiate(size); + return true; +} + +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; +} + diff --git a/src/servers/app/server/FontServer.h b/src/servers/app/server/FontServer.h new file mode 100644 index 0000000000..772e712b6a --- /dev/null +++ b/src/servers/app/server/FontServer.h @@ -0,0 +1,91 @@ +//------------------------------------------------------------------------------ +// Copyright (c) 2001-2002, OpenBeOS +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +// DEALINGS IN THE SOFTWARE. +// +// File Name: FontServer.h +// Author: DarkWyrm +// Description: Handles the largest part of the font subsystem +// +//------------------------------------------------------------------------------ +#ifndef FONTSERVER_H_ +#define FONTSERVER_H_ + +#include +#include +#include +#include +#include +#include FT_FREETYPE_H +#include FT_CACHE_H + +class FontFamily; +class FontStyle; +class ServerFont; + +/*! + \class FontServer FontServer.h + \brief Manager for the largest part of the font subsystem +*/ +class FontServer +{ +public: + FontServer(void); + ~FontServer(void); + void Lock(void); + void Unlock(void); + + /*! + \brief Determines whether the font server has started up properly + \return true if so, false if not. + */ + bool IsInitialized(void) { return init; } + int32 CountFamilies(void); + int32 CountStyles(const char *family); + void RemoveFamily(const char *family); + status_t ScanDirectory(const char *path); + void SaveList(void); + FontStyle *GetStyle(font_family family, font_style face); + ServerFont *GetSystemPlain(void); + ServerFont *GetSystemBold(void); + ServerFont *GetSystemFixed(void); + bool SetSystemPlain(const char *family, const char *style, float size); + bool SetSystemBold(const char *family, const char *style, float size); + bool SetSystemFixed(const char *family, const char *style, float size); + bool FontsNeedUpdated(void) { return need_update; } + +protected: + /*! + \brief Called when the fonts list has been updated + */ + void FontsUpdated(void) { need_update=false; } + FontFamily *_FindFamily(const char *name); + FT_CharMap _GetSupportedCharmap(const FT_Face &face); + bool init; + sem_id lock; + BList *families; + ServerFont *plain, *bold, *fixed; + bool need_update; +}; + +extern FTC_Manager ftmanager; +extern FT_Library ftlib; +extern FontServer *fontserver; + +#endif \ No newline at end of file