* 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:
@@ -11,19 +11,12 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "FontFamily.h"
|
#include "FontFamily.h"
|
||||||
#include "ServerFont.h"
|
|
||||||
#include "FontManager.h"
|
#include "FontManager.h"
|
||||||
|
|
||||||
#include <FontPrivate.h>
|
|
||||||
#include FT_CACHE_H
|
|
||||||
|
|
||||||
#include <Entry.h>
|
|
||||||
|
|
||||||
|
|
||||||
const uint32 kInvalidFamilyFlags = ~0UL;
|
const uint32 kInvalidFamilyFlags = ~0UL;
|
||||||
|
|
||||||
static BLocker sFontLock("font lock");
|
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
font_score(const FontStyle* style)
|
font_score(const FontStyle* style)
|
||||||
@@ -53,231 +46,6 @@ compare_font_styles(const FontStyle* a, const FontStyle* b)
|
|||||||
// #pragma mark -
|
// #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
|
\brief Constructor
|
||||||
\param namestr Name of the family
|
\param namestr Name of the family
|
||||||
@@ -326,7 +94,7 @@ FontFamily::Name() const
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Adds the style to the family
|
\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
|
bool
|
||||||
FontFamily::AddStyle(FontStyle *style)
|
FontFamily::AddStyle(FontStyle *style)
|
||||||
@@ -440,7 +208,8 @@ FontFamily::GetStyle(const char *styleName) const
|
|||||||
FontStyle*
|
FontStyle*
|
||||||
FontFamily::GetStyleByID(uint16 id) const
|
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);
|
FontStyle* style = fStyles.ItemAt(i);
|
||||||
if (style->ID() == id)
|
if (style->ID() == id)
|
||||||
return style;
|
return style;
|
||||||
@@ -456,7 +225,8 @@ FontFamily::GetStyleMatchingFace(uint16 face) const
|
|||||||
// we currently only use bold/italic/regular faces
|
// we currently only use bold/italic/regular faces
|
||||||
face &= B_BOLD_FACE | B_ITALIC_FACE | B_REGULAR_FACE;
|
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);
|
FontStyle* style = fStyles.ItemAt(i);
|
||||||
|
|
||||||
if (style->Face() == face)
|
if (style->Face() == face)
|
||||||
@@ -473,7 +243,8 @@ FontFamily::Flags()
|
|||||||
if (fFlags == kInvalidFamilyFlags) {
|
if (fFlags == kInvalidFamilyFlags) {
|
||||||
fFlags = 0;
|
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);
|
FontStyle* style = fStyles.ItemAt(i);
|
||||||
|
|
||||||
if (style->IsFixedWidth())
|
if (style->IsFixedWidth())
|
||||||
|
|||||||
@@ -10,177 +10,12 @@
|
|||||||
#define FONT_FAMILY_H_
|
#define FONT_FAMILY_H_
|
||||||
|
|
||||||
|
|
||||||
#include <Font.h>
|
|
||||||
#include <Locker.h>
|
|
||||||
#include <Node.h>
|
|
||||||
#include <ObjectList.h>
|
#include <ObjectList.h>
|
||||||
#include <Path.h>
|
|
||||||
#include <Rect.h>
|
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
|
|
||||||
#include <ft2build.h>
|
#include "FontStyle.h"
|
||||||
#include FT_FREETYPE_H
|
|
||||||
#include "ReferenceCounting.h"
|
|
||||||
#include "HashTable.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
|
\class FontFamily FontFamily.h
|
||||||
\brief Class representing a collection of similar styles
|
\brief Class representing a collection of similar styles
|
||||||
@@ -218,4 +53,4 @@ class FontFamily {
|
|||||||
uint32 fFlags;
|
uint32 fFlags;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* FONT_FAMILY_H_ */
|
#endif // FONT_FAMILY_H_
|
||||||
|
|||||||
@@ -0,0 +1,246 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2001-2006, Haiku.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* DarkWyrm <[email protected]>
|
||||||
|
* Axel Dörfler, [email protected]
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,170 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2001-2006, Haiku.
|
||||||
|
* Distributed under the terms of the MIT License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* DarkWyrm <[email protected]>
|
||||||
|
* Axel Dörfler, [email protected]
|
||||||
|
*/
|
||||||
|
#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_
|
||||||
@@ -4,6 +4,7 @@ UseLibraryHeaders png zlib ;
|
|||||||
UsePrivateHeaders app graphics input interface kernel shared storage ;
|
UsePrivateHeaders app graphics input interface kernel shared storage ;
|
||||||
|
|
||||||
UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing ] ;
|
UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing ] ;
|
||||||
|
UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing Painter ] ;
|
||||||
UseFreeTypeHeaders ;
|
UseFreeTypeHeaders ;
|
||||||
|
|
||||||
|
|
||||||
@@ -27,6 +28,7 @@ Server app_server :
|
|||||||
EventStream.cpp
|
EventStream.cpp
|
||||||
FontFamily.cpp
|
FontFamily.cpp
|
||||||
FontManager.cpp
|
FontManager.cpp
|
||||||
|
FontStyle.cpp
|
||||||
HashTable.cpp
|
HashTable.cpp
|
||||||
InputManager.cpp
|
InputManager.cpp
|
||||||
IntPoint.cpp
|
IntPoint.cpp
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ SharedLibrary libhaikuappserver.so :
|
|||||||
DrawState.cpp
|
DrawState.cpp
|
||||||
FontFamily.cpp
|
FontFamily.cpp
|
||||||
FontManager.cpp
|
FontManager.cpp
|
||||||
|
FontStyle.cpp
|
||||||
HashTable.cpp
|
HashTable.cpp
|
||||||
IntPoint.cpp
|
IntPoint.cpp
|
||||||
IntRect.cpp
|
IntRect.cpp
|
||||||
|
|||||||
Reference in New Issue
Block a user