* separated FontStyle and FontFamily into different .h/cpp, before they shared

FontFamily.h/cpp (just for the reason that this is how we do it mostly
  everywhere)


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21637 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stephan Aßmus 2007-07-17 20:48:06 +00:00
parent 7ca97e3548
commit fd5d46e099
6 changed files with 449 additions and 424 deletions

View File

@ -11,19 +11,12 @@
#include "FontFamily.h"
#include "ServerFont.h"
#include "FontManager.h"
#include <FontPrivate.h>
#include FT_CACHE_H
#include <Entry.h>
const uint32 kInvalidFamilyFlags = ~0UL;
static BLocker sFontLock("font lock");
static int
font_score(const FontStyle* style)
@ -53,231 +46,6 @@ compare_font_styles(const FontStyle* a, const FontStyle* b)
// #pragma mark -
/*!
\brief Constructor
\param filepath path to a font file
\param face FreeType handle for the font file after it is loaded - it will be kept open until the FontStyle is destroied
*/
FontStyle::FontStyle(node_ref& nodeRef, const char* path, FT_Face face)
: //BLocker(BString("FontStyle_").Append(face->style_name).String()),
fFreeTypeFace(face),
fName(face->style_name),
fPath(path),
fNodeRef(nodeRef),
fFamily(NULL),
fID(0),
fBounds(0, 0, 0, 0),
fFace(_TranslateStyleToFace(face->style_name))
{
fName.Truncate(B_FONT_STYLE_LENGTH);
// make sure this style can be found using the Be API
fHeight.ascent = (double)face->ascender / face->units_per_EM;
fHeight.descent = (double)-face->descender / face->units_per_EM;
// FT2's descent numbers are negative. Be's is positive
// FT2 doesn't provide a linegap, but according to the docs, we can
// calculate it because height = ascending + descending + leading
fHeight.leading = (double)(face->height - face->ascender + face->descender)
/ face->units_per_EM;
}
FontStyle::~FontStyle()
{
// make sure the font server is ours
if (fFamily != NULL && gFontManager->Lock()) {
gFontManager->RemoveStyle(this);
gFontManager->Unlock();
}
FT_Done_Face(fFreeTypeFace);
}
uint32
FontStyle::Hash() const
{
return (ID() << 16) | fFamily->ID();
}
bool
FontStyle::CompareTo(Hashable& other) const
{
// our hash values are unique (unless you have more than 65536 font families installed...)
return Hash() == other.Hash();
}
bool
FontStyle::Lock()
{
return sFontLock.Lock();
}
void
FontStyle::Unlock()
{
sFontLock.Unlock();
}
void
FontStyle::GetHeight(float size, font_height& height) const
{
height.ascent = fHeight.ascent * size;
height.descent = fHeight.descent * size;
height.leading = fHeight.leading * size;
}
/*!
\brief Returns the path to the style's font file
\return The style's font file path
*/
const char*
FontStyle::Path() const
{
return fPath.Path();
}
/*!
\brief Updates the path of the font style in case the style
has been moved around.
*/
void
FontStyle::UpdatePath(const node_ref& parentNodeRef)
{
entry_ref ref;
ref.device = parentNodeRef.device;
ref.directory = parentNodeRef.node;
ref.set_name(fPath.Leaf());
fPath.SetTo(&ref);
}
/*!
\brief Unlike BFont::Flags() this returns the extra flags field as used
in the private part of BFont.
*/
uint32
FontStyle::Flags() const
{
uint32 flags = uint32(Direction()) << B_PRIVATE_FONT_DIRECTION_SHIFT;
if (IsFixedWidth())
flags |= B_IS_FIXED;
if (TunedCount() > 0)
flags |= B_HAS_TUNED_FONT;
if (HasKerning())
flags |= B_PRIVATE_FONT_HAS_KERNING;
return flags;
}
/*!
\brief Updates the given face to match the one from this style
The specified font face often doesn't match the exact face of
a style. This method will preserve the attributes of the face
that this style does not alter, and will only update the
attributes that matter to this style.
The font renderer could then emulate the other face attributes
taking this style as a base.
*/
uint16
FontStyle::PreservedFace(uint16 face) const
{
// TODO: make this better
face &= ~(B_REGULAR_FACE | B_BOLD_FACE | B_ITALIC_FACE);
face |= Face();
return face;
}
status_t
FontStyle::UpdateFace(FT_Face face)
{
if (!sFontLock.IsLocked()) {
debugger("UpdateFace() called without having locked FontStyle!");
return B_ERROR;
}
// we only accept the face if it hasn't change its style
BString name = face->style_name;
name.Truncate(B_FONT_STYLE_LENGTH);
if (name != fName)
return B_BAD_VALUE;
FT_Done_Face(fFreeTypeFace);
fFreeTypeFace = face;
return B_OK;
}
/*!
\brief Converts an ASCII character to Unicode for the style
\param c An ASCII character
\return A Unicode value for the character
*/
// TODO: Re-enable when I understand how the FT2 Cache system changed from
// 2.1.4 to 2.1.8
/*
int16
FontStyle::ConvertToUnicode(uint16 c)
{
FT_Face f;
if(FTC_Manager_LookupFace(ftmanager,(FTC_FaceID)cachedface,&f)!=0)
return 0;
return FT_Get_Char_Index(f,c);
}
*/
void
FontStyle::_SetFontFamily(FontFamily* family, uint16 id)
{
fFamily = family;
fID = id;
}
uint16
FontStyle::_TranslateStyleToFace(const char *name) const
{
if (name == NULL)
return 0;
BString string(name);
uint16 face = 0;
if (string.IFindFirst("bold") >= 0)
face |= B_BOLD_FACE;
if (string.IFindFirst("italic") >= 0
|| string.IFindFirst("oblique") >= 0)
face |= B_ITALIC_FACE;
if (face == 0)
return B_REGULAR_FACE;
return face;
}
// #pragma mark -
/*!
\brief Constructor
\param namestr Name of the family
@ -326,7 +94,7 @@ FontFamily::Name() const
/*!
\brief Adds the style to the family
\param face FreeType face handle used to obtain info about the font
\param style pointer to FontStyle object to be added
*/
bool
FontFamily::AddStyle(FontStyle *style)
@ -440,7 +208,8 @@ FontFamily::GetStyle(const char *styleName) const
FontStyle*
FontFamily::GetStyleByID(uint16 id) const
{
for (int32 i = 0; i < fStyles.CountItems(); i++) {
int32 count = fStyles.CountItems();
for (int32 i = 0; i < count; i++) {
FontStyle* style = fStyles.ItemAt(i);
if (style->ID() == id)
return style;
@ -456,7 +225,8 @@ FontFamily::GetStyleMatchingFace(uint16 face) const
// we currently only use bold/italic/regular faces
face &= B_BOLD_FACE | B_ITALIC_FACE | B_REGULAR_FACE;
for (int32 i = 0; i < fStyles.CountItems(); i++) {
int32 count = fStyles.CountItems();
for (int32 i = 0; i < count; i++) {
FontStyle* style = fStyles.ItemAt(i);
if (style->Face() == face)
@ -473,7 +243,8 @@ FontFamily::Flags()
if (fFlags == kInvalidFamilyFlags) {
fFlags = 0;
for (int32 i = 0; i < fStyles.CountItems(); i++) {
int32 count = fStyles.CountItems();
for (int32 i = 0; i < count; i++) {
FontStyle* style = fStyles.ItemAt(i);
if (style->IsFixedWidth())

View File

@ -10,177 +10,12 @@
#define FONT_FAMILY_H_
#include <Font.h>
#include <Locker.h>
#include <Node.h>
#include <ObjectList.h>
#include <Path.h>
#include <Rect.h>
#include <String.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include "ReferenceCounting.h"
#include "HashTable.h"
#include "FontStyle.h"
struct node_ref;
class FontFamily;
class ServerFont;
enum font_format {
FONT_TRUETYPE = 0,
FONT_TYPE_1,
FONT_OPENTYPE,
FONT_BDF,
FONT_CFF,
FONT_CID,
FONT_PCF,
FONT_PFR,
FONT_SFNT,
FONT_TYPE_42,
FONT_WINFONT,
};
class FontKey : public Hashable {
public:
FontKey(uint16 familyID, uint16 styleID)
: fHash(familyID | (styleID << 16UL))
{
}
virtual ~FontKey() {};
virtual uint32 Hash() const
{ return fHash; }
virtual bool CompareTo(Hashable& other) const
{ return fHash == other.Hash(); }
private:
uint32 fHash;
};
/*!
\class FontStyle FontFamily.h
\brief Object used to represent a font style
FontStyle objects help abstract a lot of the font engine details while
still offering plenty of information the style in question.
*/
class FontStyle : public ReferenceCounting, public Hashable/*, public BLocker*/ {
public:
FontStyle(node_ref& nodeRef, const char* path, FT_Face face);
virtual ~FontStyle();
virtual uint32 Hash() const;
virtual bool CompareTo(Hashable& other) const;
const node_ref& NodeRef() const { return fNodeRef; }
bool Lock();
void Unlock();
/*!
\fn bool FontStyle::IsFixedWidth(void)
\brief Determines whether the font's character width is fixed
\return true if fixed, false if not
*/
bool IsFixedWidth() const
{ return fFreeTypeFace->face_flags & FT_FACE_FLAG_FIXED_WIDTH; }
/*!
\fn bool FontStyle::IsScalable(void)
\brief Determines whether the font can be scaled to any size
\return true if scalable, false if not
*/
bool IsScalable() const
{ return fFreeTypeFace->face_flags & FT_FACE_FLAG_SCALABLE; }
/*!
\fn bool FontStyle::HasKerning(void)
\brief Determines whether the font has kerning information
\return true if kerning info is available, false if not
*/
bool HasKerning() const
{ return fFreeTypeFace->face_flags & FT_FACE_FLAG_KERNING; }
/*!
\fn bool FontStyle::HasTuned(void)
\brief Determines whether the font contains strikes
\return true if it has strikes included, false if not
*/
bool HasTuned() const
{ return fFreeTypeFace->num_fixed_sizes > 0; }
/*!
\fn bool FontStyle::TunedCount(void)
\brief Returns the number of strikes the style contains
\return The number of strikes the style contains
*/
int32 TunedCount() const
{ return fFreeTypeFace->num_fixed_sizes; }
/*!
\fn bool FontStyle::GlyphCount(void)
\brief Returns the number of glyphs in the style
\return The number of glyphs the style contains
*/
uint16 GlyphCount() const
{ return fFreeTypeFace->num_glyphs; }
/*!
\fn bool FontStyle::CharMapCount(void)
\brief Returns the number of character maps the style contains
\return The number of character maps the style contains
*/
uint16 CharMapCount() const
{ return fFreeTypeFace->num_charmaps; }
const char* Name() const
{ return fName.String(); }
FontFamily* Family() const
{ return fFamily; }
uint16 ID() const
{ return fID; }
uint32 Flags() const;
uint16 Face() const
{ return fFace; }
uint16 PreservedFace(uint16) const;
const char* Path() const;
void UpdatePath(const node_ref& parentNodeRef);
void GetHeight(float size, font_height &heigth) const;
font_direction Direction() const
{ return B_FONT_LEFT_TO_RIGHT; }
font_file_format FileFormat() const
{ return B_TRUETYPE_WINDOWS; }
FT_Face FreeTypeFace() const
{ return fFreeTypeFace; }
status_t UpdateFace(FT_Face face);
// TODO: Re-enable when I understand how the FT2 Cache system changed from
// 2.1.4 to 2.1.8
// int16 ConvertToUnicode(uint16 c);
private:
friend class FontFamily;
uint16 _TranslateStyleToFace(const char *name) const;
void _SetFontFamily(FontFamily* family, uint16 id);
private:
FT_Face fFreeTypeFace;
BString fName;
BPath fPath;
node_ref fNodeRef;
FontFamily* fFamily;
uint16 fID;
BRect fBounds;
font_height fHeight;
uint16 fFace;
};
/*!
\class FontFamily FontFamily.h
\brief Class representing a collection of similar styles
@ -189,33 +24,33 @@ class FontStyle : public ReferenceCounting, public Hashable/*, public BLocker*/
Arial Roman, Arial Italic, Arial Bold, etc.
*/
class FontFamily {
public:
FontFamily(const char* name, uint16 id);
virtual ~FontFamily();
public:
FontFamily(const char* name, uint16 id);
virtual ~FontFamily();
const char* Name() const;
const char* Name() const;
bool AddStyle(FontStyle* style);
bool RemoveStyle(FontStyle* style);
bool AddStyle(FontStyle* style);
bool RemoveStyle(FontStyle* style);
FontStyle* GetStyle(const char* style) const;
FontStyle* GetStyleMatchingFace(uint16 face) const;
FontStyle* GetStyleByID(uint16 face) const;
FontStyle* GetStyle(const char* style) const;
FontStyle* GetStyleMatchingFace(uint16 face) const;
FontStyle* GetStyleByID(uint16 face) const;
uint16 ID() const
{ return fID; }
uint32 Flags();
uint16 ID() const
{ return fID; }
uint32 Flags();
bool HasStyle(const char* style) const;
int32 CountStyles() const;
FontStyle* StyleAt(int32 index) const;
bool HasStyle(const char* style) const;
int32 CountStyles() const;
FontStyle* StyleAt(int32 index) const;
private:
BString fName;
BObjectList<FontStyle> fStyles;
uint16 fID;
uint16 fNextID;
uint32 fFlags;
BString fName;
BObjectList<FontStyle> fStyles;
uint16 fID;
uint16 fNextID;
uint32 fFlags;
};
#endif /* FONT_FAMILY_H_ */
#endif // FONT_FAMILY_H_

View File

@ -0,0 +1,246 @@
/*
* Copyright 2001-2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* DarkWyrm <bpmagic@columbus.rr.com>
* Axel Dörfler, axeld@pinc-software.de
*/
/** Classes to represent font styles and families */
#include "FontFamily.h"
#include "ServerFont.h"
#include "FontManager.h"
#include <FontPrivate.h>
#include <Entry.h>
static BLocker sFontLock("font lock");
/*!
\brief Constructor
\param filepath path to a font file
\param face FreeType handle for the font file after it is loaded - it will be kept open until the FontStyle is destroied
*/
FontStyle::FontStyle(node_ref& nodeRef, const char* path, FT_Face face)
: //BLocker(BString("FontStyle_").Append(face->style_name).String()),
fFreeTypeFace(face),
fName(face->style_name),
fPath(path),
fNodeRef(nodeRef),
fFamily(NULL),
fID(0),
fBounds(0, 0, 0, 0),
fFace(_TranslateStyleToFace(face->style_name))
{
fName.Truncate(B_FONT_STYLE_LENGTH);
// make sure this style can be found using the Be API
fHeight.ascent = (double)face->ascender / face->units_per_EM;
fHeight.descent = (double)-face->descender / face->units_per_EM;
// FT2's descent numbers are negative. Be's is positive
// FT2 doesn't provide a linegap, but according to the docs, we can
// calculate it because height = ascending + descending + leading
fHeight.leading = (double)(face->height - face->ascender + face->descender)
/ face->units_per_EM;
}
FontStyle::~FontStyle()
{
// make sure the font server is ours
if (fFamily != NULL && gFontManager->Lock()) {
gFontManager->RemoveStyle(this);
gFontManager->Unlock();
}
FT_Done_Face(fFreeTypeFace);
}
uint32
FontStyle::Hash() const
{
return (ID() << 16) | fFamily->ID();
}
bool
FontStyle::CompareTo(Hashable& other) const
{
// our hash values are unique (unless you have more than 65536 font families installed...)
return Hash() == other.Hash();
}
bool
FontStyle::Lock()
{
return sFontLock.Lock();
}
void
FontStyle::Unlock()
{
sFontLock.Unlock();
}
void
FontStyle::GetHeight(float size, font_height& height) const
{
height.ascent = fHeight.ascent * size;
height.descent = fHeight.descent * size;
height.leading = fHeight.leading * size;
}
/*!
\brief Returns the path to the style's font file
\return The style's font file path
*/
const char*
FontStyle::Path() const
{
return fPath.Path();
}
/*!
\brief Updates the path of the font style in case the style
has been moved around.
*/
void
FontStyle::UpdatePath(const node_ref& parentNodeRef)
{
entry_ref ref;
ref.device = parentNodeRef.device;
ref.directory = parentNodeRef.node;
ref.set_name(fPath.Leaf());
fPath.SetTo(&ref);
}
/*!
\brief Unlike BFont::Flags() this returns the extra flags field as used
in the private part of BFont.
*/
uint32
FontStyle::Flags() const
{
uint32 flags = uint32(Direction()) << B_PRIVATE_FONT_DIRECTION_SHIFT;
if (IsFixedWidth())
flags |= B_IS_FIXED;
if (TunedCount() > 0)
flags |= B_HAS_TUNED_FONT;
if (HasKerning())
flags |= B_PRIVATE_FONT_HAS_KERNING;
return flags;
}
/*!
\brief Updates the given face to match the one from this style
The specified font face often doesn't match the exact face of
a style. This method will preserve the attributes of the face
that this style does not alter, and will only update the
attributes that matter to this style.
The font renderer could then emulate the other face attributes
taking this style as a base.
*/
uint16
FontStyle::PreservedFace(uint16 face) const
{
// TODO: make this better
face &= ~(B_REGULAR_FACE | B_BOLD_FACE | B_ITALIC_FACE);
face |= Face();
return face;
}
status_t
FontStyle::UpdateFace(FT_Face face)
{
if (!sFontLock.IsLocked()) {
debugger("UpdateFace() called without having locked FontStyle!");
return B_ERROR;
}
// we only accept the face if it hasn't change its style
BString name = face->style_name;
name.Truncate(B_FONT_STYLE_LENGTH);
if (name != fName)
return B_BAD_VALUE;
FT_Done_Face(fFreeTypeFace);
fFreeTypeFace = face;
return B_OK;
}
/*!
\brief Converts an ASCII character to Unicode for the style
\param c An ASCII character
\return A Unicode value for the character
*/
// TODO: Re-enable when I understand how the FT2 Cache system changed from
// 2.1.4 to 2.1.8
/*
int16
FontStyle::ConvertToUnicode(uint16 c)
{
FT_Face f;
if(FTC_Manager_LookupFace(ftmanager,(FTC_FaceID)cachedface,&f)!=0)
return 0;
return FT_Get_Char_Index(f,c);
}
*/
void
FontStyle::_SetFontFamily(FontFamily* family, uint16 id)
{
fFamily = family;
fID = id;
}
uint16
FontStyle::_TranslateStyleToFace(const char *name) const
{
if (name == NULL)
return 0;
BString string(name);
uint16 face = 0;
if (string.IFindFirst("bold") >= 0)
face |= B_BOLD_FACE;
if (string.IFindFirst("italic") >= 0
|| string.IFindFirst("oblique") >= 0)
face |= B_ITALIC_FACE;
if (face == 0)
return B_REGULAR_FACE;
return face;
}

170
src/servers/app/FontStyle.h Normal file
View File

@ -0,0 +1,170 @@
/*
* Copyright 2001-2006, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* DarkWyrm <bpmagic@columbus.rr.com>
* Axel Dörfler, axeld@pinc-software.de
*/
#ifndef FONT_STYLE_H_
#define FONT_STYLE_H_
#include <Font.h>
#include <Locker.h>
#include <Node.h>
#include <ObjectList.h>
#include <Path.h>
#include <Rect.h>
#include <String.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include "ReferenceCounting.h"
#include "HashTable.h"
struct node_ref;
class FontFamily;
class ServerFont;
class FontKey : public Hashable {
public:
FontKey(uint16 familyID, uint16 styleID)
: fHash(familyID | (styleID << 16UL))
{
}
virtual ~FontKey() {};
virtual uint32 Hash() const
{ return fHash; }
virtual bool CompareTo(Hashable& other) const
{ return fHash == other.Hash(); }
private:
uint32 fHash;
};
/*!
\class FontStyle FontStyle.h
\brief Object used to represent a font style
FontStyle objects help abstract a lot of the font engine details while
still offering plenty of information the style in question.
*/
class FontStyle : public ReferenceCounting, public Hashable/*, public BLocker*/ {
public:
FontStyle(node_ref& nodeRef, const char* path, FT_Face face);
virtual ~FontStyle();
virtual uint32 Hash() const;
virtual bool CompareTo(Hashable& other) const;
const node_ref& NodeRef() const { return fNodeRef; }
bool Lock();
void Unlock();
/*!
\fn bool FontStyle::IsFixedWidth(void)
\brief Determines whether the font's character width is fixed
\return true if fixed, false if not
*/
bool IsFixedWidth() const
{ return fFreeTypeFace->face_flags & FT_FACE_FLAG_FIXED_WIDTH; }
/*!
\fn bool FontStyle::IsScalable(void)
\brief Determines whether the font can be scaled to any size
\return true if scalable, false if not
*/
bool IsScalable() const
{ return fFreeTypeFace->face_flags & FT_FACE_FLAG_SCALABLE; }
/*!
\fn bool FontStyle::HasKerning(void)
\brief Determines whether the font has kerning information
\return true if kerning info is available, false if not
*/
bool HasKerning() const
{ return fFreeTypeFace->face_flags & FT_FACE_FLAG_KERNING; }
/*!
\fn bool FontStyle::HasTuned(void)
\brief Determines whether the font contains strikes
\return true if it has strikes included, false if not
*/
bool HasTuned() const
{ return fFreeTypeFace->num_fixed_sizes > 0; }
/*!
\fn bool FontStyle::TunedCount(void)
\brief Returns the number of strikes the style contains
\return The number of strikes the style contains
*/
int32 TunedCount() const
{ return fFreeTypeFace->num_fixed_sizes; }
/*!
\fn bool FontStyle::GlyphCount(void)
\brief Returns the number of glyphs in the style
\return The number of glyphs the style contains
*/
uint16 GlyphCount() const
{ return fFreeTypeFace->num_glyphs; }
/*!
\fn bool FontStyle::CharMapCount(void)
\brief Returns the number of character maps the style contains
\return The number of character maps the style contains
*/
uint16 CharMapCount() const
{ return fFreeTypeFace->num_charmaps; }
const char* Name() const
{ return fName.String(); }
FontFamily* Family() const
{ return fFamily; }
uint16 ID() const
{ return fID; }
uint32 Flags() const;
uint16 Face() const
{ return fFace; }
uint16 PreservedFace(uint16) const;
const char* Path() const;
void UpdatePath(const node_ref& parentNodeRef);
void GetHeight(float size, font_height &heigth) const;
font_direction Direction() const
{ return B_FONT_LEFT_TO_RIGHT; }
font_file_format FileFormat() const
{ return B_TRUETYPE_WINDOWS; }
FT_Face FreeTypeFace() const
{ return fFreeTypeFace; }
status_t UpdateFace(FT_Face face);
// TODO: Re-enable when I understand how the FT2 Cache system changed from
// 2.1.4 to 2.1.8
// int16 ConvertToUnicode(uint16 c);
private:
friend class FontFamily;
uint16 _TranslateStyleToFace(const char *name) const;
void _SetFontFamily(FontFamily* family, uint16 id);
private:
FT_Face fFreeTypeFace;
BString fName;
BPath fPath;
node_ref fNodeRef;
FontFamily* fFamily;
uint16 fID;
BRect fBounds;
font_height fHeight;
uint16 fFace;
};
#endif // FONT_STYLE_H_

View File

@ -4,6 +4,7 @@ UseLibraryHeaders png zlib ;
UsePrivateHeaders app graphics input interface kernel shared storage ;
UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing ] ;
UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing Painter ] ;
UseFreeTypeHeaders ;
@ -27,6 +28,7 @@ Server app_server :
EventStream.cpp
FontFamily.cpp
FontManager.cpp
FontStyle.cpp
HashTable.cpp
InputManager.cpp
IntPoint.cpp

View File

@ -65,6 +65,7 @@ SharedLibrary libhaikuappserver.so :
DrawState.cpp
FontFamily.cpp
FontManager.cpp
FontStyle.cpp
HashTable.cpp
IntPoint.cpp
IntRect.cpp