2003-01-01 01:19:48 +03:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
// 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: FontFamily.cpp
|
|
|
|
// Author: DarkWyrm <bpmagic@columbus.rr.com>
|
|
|
|
// Description: classes to represent font styles and families
|
|
|
|
//
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
#include "FontFamily.h"
|
|
|
|
#include "ServerFont.h"
|
|
|
|
#include FT_CACHE_H
|
|
|
|
|
|
|
|
extern FTC_Manager ftmanager;
|
|
|
|
|
|
|
|
/*!
|
2003-01-18 23:32:45 +03:00
|
|
|
\brief Constructor
|
2003-01-20 02:04:58 +03:00
|
|
|
\param filepath path to a font file
|
2003-01-01 01:19:48 +03:00
|
|
|
\param face FreeType handle for the font file after it is loaded - for its info only
|
|
|
|
*/
|
|
|
|
FontStyle::FontStyle(const char *filepath, FT_Face face)
|
|
|
|
{
|
|
|
|
name=new BString(face->style_name);
|
|
|
|
cachedface=new CachedFaceRec;
|
|
|
|
cachedface->file_path=filepath;
|
|
|
|
family=NULL;
|
|
|
|
instances=new BList(0);
|
|
|
|
has_bitmaps=(face->num_fixed_sizes>0)?true:false;
|
|
|
|
is_fixedwidth=(face->face_flags & FT_FACE_FLAG_FIXED_WIDTH)?true:false;
|
|
|
|
is_scalable=(face->face_flags & FT_FACE_FLAG_SCALABLE)?true:false;
|
|
|
|
has_kerning=(face->face_flags & FT_FACE_FLAG_KERNING)?true:false;
|
|
|
|
glyphcount=face->num_glyphs;
|
|
|
|
charmapcount=face->num_charmaps;
|
|
|
|
tunedcount=face->num_fixed_sizes;
|
|
|
|
path=new BString(filepath);
|
|
|
|
fbounds.Set(0,0,0,0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
2003-01-18 23:32:45 +03:00
|
|
|
\brief Destructor
|
2003-01-01 01:19:48 +03:00
|
|
|
|
|
|
|
Frees all data allocated on the heap. All child ServerFonts are marked as having
|
|
|
|
a NULL style so that each ServerFont knows that it is running on borrowed time.
|
|
|
|
This is done because a FontStyle should be deleted only when it no longer has any
|
|
|
|
dependencies.
|
|
|
|
*/
|
|
|
|
FontStyle::~FontStyle(void)
|
|
|
|
{
|
|
|
|
delete name;
|
|
|
|
delete path;
|
|
|
|
delete cachedface;
|
|
|
|
|
|
|
|
// Mark all instances as Free here
|
|
|
|
int32 index=0;
|
|
|
|
|
|
|
|
ServerFont *fs=(ServerFont*)instances->ItemAt(index);
|
|
|
|
|
|
|
|
while(fs)
|
|
|
|
{
|
|
|
|
fs->fstyle=NULL;
|
|
|
|
index++;
|
|
|
|
fs=(ServerFont*)instances->ItemAt(index);
|
|
|
|
}
|
|
|
|
|
|
|
|
instances->MakeEmpty();
|
|
|
|
delete instances;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\brief Returns the name of the style as a string
|
|
|
|
\return The style's name
|
|
|
|
*/
|
|
|
|
const char *FontStyle::Name(void)
|
|
|
|
{
|
|
|
|
return path->String();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\brief Returns a handle to the style in question, straight from FreeType's cache
|
|
|
|
\return FreeType face handle or NULL if there was an internal error
|
|
|
|
*/
|
|
|
|
FT_Face FontStyle::GetFace(void)
|
|
|
|
{
|
|
|
|
FT_Face f;
|
|
|
|
return (FTC_Manager_Lookup_Face(ftmanager,cachedface,&f)!=0)?f:NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\brief Returns the path to the style's font file
|
|
|
|
\return The style's font file path
|
|
|
|
*/
|
|
|
|
const char *FontStyle::GetPath(void)
|
|
|
|
{
|
|
|
|
return path->String();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\brief Converts an ASCII character to Unicode for the style
|
2003-01-20 02:04:58 +03:00
|
|
|
\param c An ASCII character
|
2003-01-01 01:19:48 +03:00
|
|
|
\return A Unicode value for the character
|
|
|
|
*/
|
|
|
|
int16 FontStyle::ConvertToUnicode(uint16 c)
|
|
|
|
{
|
|
|
|
FT_Face f;
|
|
|
|
if(FTC_Manager_Lookup_Face(ftmanager,cachedface,&f)!=0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return FT_Get_Char_Index(f,c);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\brief Creates a new ServerFont object for the style, given size, shear, and rotation.
|
2003-01-20 02:04:58 +03:00
|
|
|
\param size character size in points
|
|
|
|
\param rotation rotation in degrees
|
|
|
|
\param shear shear (slant) in degrees. 45 <= shear <= 135. 90 is vertical
|
2003-01-01 01:19:48 +03:00
|
|
|
\return The new ServerFont object
|
|
|
|
*/
|
2003-06-23 06:54:52 +04:00
|
|
|
ServerFont *FontStyle::Instantiate(float size, float rotation, float shear)
|
2003-01-01 01:19:48 +03:00
|
|
|
{
|
|
|
|
ServerFont *f=new ServerFont(this, size, rotation, shear);
|
|
|
|
instances->AddItem(f);
|
|
|
|
return f;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\brief Constructor
|
2003-01-20 02:04:58 +03:00
|
|
|
\param namestr Name of the family
|
2003-01-01 01:19:48 +03:00
|
|
|
*/
|
|
|
|
FontFamily::FontFamily(const char *namestr)
|
|
|
|
{
|
|
|
|
name=new BString(namestr);
|
|
|
|
styles=new BList(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\brief Destructor
|
|
|
|
|
|
|
|
Deletes all child styles. Note that a FontFamily should not be deleted unless
|
|
|
|
its styles have no dependencies or some other really good reason, such as
|
|
|
|
system shutdown.
|
|
|
|
*/
|
|
|
|
FontFamily::~FontFamily(void)
|
|
|
|
{
|
|
|
|
delete name;
|
|
|
|
|
|
|
|
BString *string;
|
|
|
|
for(int32 i=0; i<styles->CountItems(); i++)
|
|
|
|
{
|
|
|
|
string=(BString *)styles->RemoveItem(i);
|
|
|
|
if(string)
|
|
|
|
delete string;
|
|
|
|
}
|
|
|
|
styles->MakeEmpty(); // should be empty, but just in case...
|
|
|
|
delete styles;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\brief Returns the name of the family
|
|
|
|
\return The family's name
|
|
|
|
*/
|
|
|
|
const char *FontFamily::Name(void)
|
|
|
|
{
|
|
|
|
return name->String();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\brief Adds the style to the family
|
2003-01-20 02:04:58 +03:00
|
|
|
\param path full path to the style's font file
|
|
|
|
\param face FreeType face handle used to obtain info about the font
|
2003-01-01 01:19:48 +03:00
|
|
|
*/
|
|
|
|
void FontFamily::AddStyle(const char *path,FT_Face face)
|
|
|
|
{
|
|
|
|
if(!path)
|
|
|
|
return;
|
|
|
|
|
|
|
|
BString style(face->style_name);
|
|
|
|
FontStyle *item;
|
|
|
|
|
|
|
|
// Don't add if it already is in the family.
|
|
|
|
int32 count=styles->CountItems();
|
|
|
|
for(int32 i=0; i<count; i++)
|
|
|
|
{
|
|
|
|
item=(FontStyle *)styles->ItemAt(i);
|
|
|
|
if(item->name->Compare(face->style_name)==0)
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
item=new FontStyle(path, face);
|
|
|
|
item->family=this;
|
|
|
|
styles->AddItem(item);
|
|
|
|
AddDependent();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\brief Removes a style from the family and deletes it
|
2003-01-20 02:04:58 +03:00
|
|
|
\param style Name of the style to be removed from the family
|
2003-01-01 01:19:48 +03:00
|
|
|
*/
|
|
|
|
void FontFamily::RemoveStyle(const char *style)
|
|
|
|
{
|
|
|
|
int32 count=styles->CountItems();
|
|
|
|
if(!style || count<1)
|
|
|
|
return;
|
|
|
|
|
|
|
|
FontStyle *fs;
|
|
|
|
for(int32 i=0; i<count; i++)
|
|
|
|
{
|
|
|
|
fs=(FontStyle *)styles->ItemAt(i);
|
|
|
|
if(fs && fs->name->Compare(style)==0)
|
|
|
|
{
|
|
|
|
fs=(FontStyle *)styles->RemoveItem(i);
|
|
|
|
if(fs)
|
|
|
|
{
|
|
|
|
delete fs;
|
|
|
|
RemoveDependent();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\brief Returns the number of styles in the family
|
|
|
|
\return The number of styles in the family
|
|
|
|
*/
|
|
|
|
int32 FontFamily::CountStyles(void)
|
|
|
|
{
|
|
|
|
return styles->CountItems();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\brief Determines whether the style belongs to the family
|
2003-01-20 02:04:58 +03:00
|
|
|
\param style Name of the style being checked
|
2003-01-01 01:19:48 +03:00
|
|
|
\return True if it belongs, false if not
|
|
|
|
*/
|
|
|
|
bool FontFamily::HasStyle(const char *style)
|
|
|
|
{
|
|
|
|
int32 count=styles->CountItems();
|
|
|
|
if(!style || count<1)
|
|
|
|
return false;
|
|
|
|
FontStyle *fs;
|
|
|
|
for(int32 i=0; i<count; i++)
|
|
|
|
{
|
|
|
|
fs=(FontStyle *)styles->ItemAt(i);
|
|
|
|
if(fs && fs->name->Compare(style)==0)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\brief Returns the name of a style in the family
|
2003-01-20 02:04:58 +03:00
|
|
|
\param index list index of the style to be found
|
2003-01-01 01:19:48 +03:00
|
|
|
\return name of the style or NULL if the index is not valid
|
|
|
|
*/
|
|
|
|
const char *FontFamily::GetStyle(int32 index)
|
|
|
|
{
|
|
|
|
FontStyle *fs=(FontStyle*)styles->ItemAt(index);
|
|
|
|
if(!fs)
|
|
|
|
return NULL;
|
|
|
|
return fs->Name();
|
|
|
|
}
|
|
|
|
|
|
|
|
/*!
|
|
|
|
\brief Get the FontStyle object for the name given
|
2003-01-20 02:04:58 +03:00
|
|
|
\param style Name of the style to be obtained
|
2003-01-01 01:19:48 +03:00
|
|
|
\return The FontStyle object or NULL if none was found.
|
|
|
|
|
|
|
|
The object returned belongs to the family and must not be deleted.
|
|
|
|
*/
|
|
|
|
FontStyle *FontFamily::GetStyle(const char *style)
|
|
|
|
{
|
|
|
|
int32 count=styles->CountItems();
|
|
|
|
if(!style || count<1)
|
|
|
|
return NULL;
|
|
|
|
FontStyle *fs;
|
|
|
|
for(int32 i=0; i<count; i++)
|
|
|
|
{
|
|
|
|
fs=(FontStyle *)styles->ItemAt(i);
|
|
|
|
if(fs && fs->name->Compare(style)==0)
|
|
|
|
return fs;
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|