Fixed a bunch of bugs in the font sub-system:

* BFont::Face() was almost always wrong - also on the server side,
  _TranslateStyleToFace() was broken.
* a clean font was not correctly initialized to be_plain_font
* BFont::GetFamilyAndStyle() did not work correctly if either family
  or style was NULL - which is allowed, and shouldn't have let it abort
  its task.
* FontServer::GetStyle() by ID did not work reliably under certain
  circumstances (but those were not reached with the current server)
* BFont::SetFamilyAndStyle() did not work when family was NULL, and
  it also never set fFace correctly.
* Introduced a FontFamily::GetStyleWithFace()
* Renamed some FontFamily/FontStyle methods from ie. GetID() to ID()
  to match the style used everywhere else in BeOS.
* Removed AS_SET_FAMILY_NAME as its no longer in use.
* Lots of cleanup and simplification.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14602 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2005-10-31 23:21:36 +00:00
parent 0083a1f3f5
commit 9b1ad6f45e
8 changed files with 339 additions and 348 deletions

View File

@ -30,7 +30,7 @@
#include <String.h>
#include <Rect.h>
#include <Font.h>
#include <List.h>
#include <ObjectList.h>
#include <Locker.h>
#include <ft2build.h>
#include FT_FREETYPE_H
@ -39,9 +39,8 @@
class FontFamily;
class ServerFont;
enum font_format
{
FONT_TRUETYPE=0,
enum font_format {
FONT_TRUETYPE = 0,
FONT_TYPE_1,
FONT_OPENTYPE,
FONT_BDF,
@ -69,8 +68,7 @@ typedef struct CachedFaceRec_
such. Each value must be multiplied by the point size to determine size in pixels
*/
typedef struct
{
typedef struct {
FT_Short ascent;
FT_Short descent;
FT_Short leading;
@ -85,103 +83,107 @@ typedef struct
still offering plenty of information the style in question.
*/
class FontStyle : public SharedObject, public BLocker {
public:
public:
FontStyle(const char* filepath,
FT_Face face);
virtual ~FontStyle();
FT_Face face);
virtual ~FontStyle();
/*!
\fn bool FontStyle::IsFixedWidth(void)
\brief Determines whether the font's character width is fixed
\return true if fixed, false if not
*/
inline bool IsFixedWidth() const
inline bool IsFixedWidth() const
{ return fFTFace->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
*/
inline bool IsScalable() const
inline bool IsScalable() const
{ return fFTFace->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
*/
inline bool HasKerning() const
inline bool HasKerning() const
{ return fFTFace->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
*/
inline bool HasTuned() const
inline bool HasTuned() const
{ return fFTFace->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
*/
inline int32 TunedCount() const
inline int32 TunedCount() const
{ return fFTFace->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
*/
inline uint16 GlyphCount() const
inline uint16 GlyphCount() const
{ return fFTFace->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
*/
inline uint16 CharMapCount() const
inline uint16 CharMapCount() const
{ return fFTFace->num_charmaps; }
const char* Name() const;
inline FontFamily* Family() const
const char* Name() const;
inline FontFamily* Family() const
{ return fFontFamily; }
inline uint16 GetID() const
inline uint16 ID() const
{ return fID; }
int32 GetFlags() const;
int32 Flags() const;
inline uint16 GetFace() const
inline uint16 Face() const
{ return fFace; }
const char* GetPath() const;
font_height GetHeight(const float& size) const;
const char* Path() const;
font_height GetHeight(const float& size) const;
inline FT_Face GetFTFace() const
inline FT_Face GetFTFace() const
{ return fFTFace; }
// TODO: Re-enable when I understand how the FT2 Cache system changed from
// 2.1.4 to 2.1.8
// int16 ConvertToUnicode(uint16 c);
void AttachedToFamily(FontFamily* family);
void DetachedFromFamily();
// int16 ConvertToUnicode(uint16 c);
protected:
uint16 TranslateStyleToFace(const char *name) const;
friend class FontFamily;
void AttachedToFamily(FontFamily* family);
void DetachedFromFamily();
FT_Face fFTFace;
// CachedFace cachedface;
private:
friend class FontFamily;
uint16 _TranslateStyleToFace(const char *name) const;
void _SetFontFamily(FontFamily* family)
{ fFontFamily = family; }
void _SetID(uint16 id)
{ fID = id; }
FontFamily* fFontFamily;
private:
FT_Face fFTFace;
// CachedFace cachedface;
BString fName;
BString fPath;
FontFamily* fFontFamily;
BRect fBounds;
BString fName;
BString fPath;
uint16 fID;
uint16 fFace;
BRect fBounds;
FontStyleHeight fHeight;
uint16 fID;
uint16 fFace;
FontStyleHeight fHeight;
};
/*!
@ -192,32 +194,34 @@ protected:
Arial Roman, Arial Italic, Arial Bold, etc.
*/
class FontFamily : public SharedObject {
public:
FontFamily(const char* namestr,
const uint16& index);
virtual ~FontFamily();
public:
FontFamily(const char* namestr,
const uint16& index);
virtual ~FontFamily();
const char* Name() const;
bool AddStyle(FontStyle* style);
void RemoveStyle(const char* style);
void RemoveStyle(FontStyle* style);
FontStyle* GetStyle(int32 index) const;
FontStyle* GetStyle(const char* style) const;
uint16 GetID() const
{ return fID; }
bool HasStyle(const char* style) const;
int32 CountStyles() const;
int32 GetFlags();
protected:
BString fName;
BList fStyles;
uint16 fID;
int32 fFlags;
const char* Name() const;
bool AddStyle(FontStyle* style);
void RemoveStyle(const char* style);
void RemoveStyle(FontStyle* style);
FontStyle* GetStyle(const char* style) const;
FontStyle* GetStyleWithFace(uint16 face) const;
FontStyle* GetStyleWithID(uint16 face) const;
uint16 ID() const
{ return fID; }
int32 Flags();
bool HasStyle(const char* style) const;
int32 CountStyles() const;
FontStyle* StyleAt(int32 index) const;
protected:
BString fName;
BObjectList<FontStyle> fStyles;
uint16 fID;
int32 fFlags;
};
#endif
#endif /* FONT_FAMILY_H_ */

View File

@ -28,43 +28,43 @@ class ServerFont;
*/
class FontServer : public BLocker {
public:
FontServer(void);
~FontServer(void);
FontServer();
~FontServer();
/*!
\brief Determines whether the font server has started up properly
\return true if so, false if not.
*/
bool IsInitialized(void) { return fInit; }
int32 CountFamilies(void);
bool IsInitialized() { return fInit; }
int32 CountFamilies();
int32 CountStyles(const char *family);
void RemoveFamily(const char *family);
void ScanSystemFolders(void);
void ScanSystemFolders();
status_t ScanDirectory(const char *path);
void SaveList(void);
void SaveList();
const char *GetFamilyName(uint16 id) const;
const char *GetStyleName(const char *family, uint16 id) const;
FontStyle *GetStyle(const char *family, const char *face);
FontStyle *GetStyle(const char *family, const char *style, uint16 face = 0);
FontStyle *GetStyle(const char *family, uint16 id) const;
FontStyle *GetStyle(const uint16 &familyid, const uint16 &styleid);
FontFamily *GetFamily(const uint16 &familyid) const;
FontStyle *GetStyle(uint16 familyID, uint16 styleID);
FontFamily *GetFamily(uint16 familyID) const;
FontFamily *GetFamily(const char *name) const;
ServerFont *GetSystemPlain(void);
ServerFont *GetSystemBold(void);
ServerFont *GetSystemFixed(void);
ServerFont *GetSystemPlain();
ServerFont *GetSystemBold();
ServerFont *GetSystemFixed();
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 fNeedUpdate; }
bool FontsNeedUpdated() { return fNeedUpdate; }
/*!
\brief Called when the fonts list has been updated
*/
void FontsUpdated(void) { fNeedUpdate = false; }
void FontsUpdated() { fNeedUpdate = false; }
protected:
uint16 TranslateStyleToFace(const char *name) const;

View File

@ -66,16 +66,16 @@ class ServerFont {
const char* GetStyle() const;
const char* GetFamily() const;
const char* GetPath() const
{ return fStyle->GetPath(); }
{ return fStyle->Path(); }
status_t SetFamilyAndStyle(uint16 familyID,
uint16 styleID);
status_t SetFamilyAndStyle(uint32 fontID);
uint16 StyleID() const
{ return fStyle->GetID(); }
{ return fStyle->ID(); }
uint16 FamilyID() const
{ return fStyle->Family()->GetID(); }
{ return fStyle->Family()->ID(); }
uint32 GetFamilyAndStyle() const;

View File

@ -3,9 +3,12 @@
* Distributed under the terms of the MIT License.
*
* Authors:
* DarkWyrm <bpmagic@columbus.rr.com>
* Jérôme Duval, jerome.duval@free.fr
* DarkWyrm <bpmagic@columbus.rr.com>
* Jérôme Duval, jerome.duval@free.fr
* Axel Dörfler, axeld@pinc-software.de
*/
#include <stdio.h>
#include <stdlib.h>
@ -22,9 +25,6 @@
#include <Font.h>
//----------------------------------------------------------------------------------------
// Globals
//----------------------------------------------------------------------------------------
// The actual objects which the globals point to
static BFont sPlainFont;
@ -39,9 +39,9 @@ const BFont *be_fixed_font = &sFixedFont;
extern "C" void
_init_global_fonts()
{
_font_control_(&sPlainFont,AS_SET_SYSFONT_PLAIN,NULL);
_font_control_(&sBoldFont,AS_SET_SYSFONT_BOLD,NULL);
_font_control_(&sFixedFont,AS_SET_SYSFONT_FIXED,NULL);
_font_control_(&sPlainFont, AS_SET_SYSFONT_PLAIN, NULL);
_font_control_(&sBoldFont, AS_SET_SYSFONT_BOLD, NULL);
_font_control_(&sFixedFont, AS_SET_SYSFONT_FIXED, NULL);
}
@ -73,8 +73,6 @@ _font_control_(BFont *font, int32 cmd, void *data)
if (link.FlushWithReply(code) != B_OK
|| code != SERVER_TRUE) {
// Once again, this shouldn't ever happen, but I want to know about it
// if it does
printf("DEBUG: Couldn't initialize font in _font_control()\n");
return;
}
@ -89,6 +87,7 @@ _font_control_(BFont *font, int32 cmd, void *data)
link.Read<uint32>(&font->fFlags);
}
/*!
\brief Private function used to replace the R5 hack which sets a system font
\param which string denoting which font to set
@ -101,14 +100,14 @@ _font_control_(BFont *font, int32 cmd, void *data)
*/
void
_set_system_font_(const char *which, font_family family, font_style style,
float size)
float size)
{
if (!which)
return;
if (!strcmp(which,"plain")
|| !strcmp(which,"bold")
|| !strcmp(which,"fixed")) {
if (!strcmp(which, "plain")
|| !strcmp(which, "bold")
|| !strcmp(which, "fixed")) {
BPrivate::AppServerLink link;
link.StartMessage(AS_SET_SYSTEM_FONT);
@ -179,7 +178,7 @@ get_font_family(int32 index, font_family *name, uint32 *flags)
{
// Fix over R5, which does not check for NULL font family names - it just crashes
if (!name)
return B_ERROR;
return B_BAD_VALUE;
int32 code;
BPrivate::AppServerLink link;
@ -214,8 +213,8 @@ status_t
get_font_style(font_family family, int32 index, font_style *name,
uint32 *flags)
{
if(!name)
return B_ERROR;
if (!name)
return B_BAD_VALUE;
int32 code;
BPrivate::AppServerLink link;
@ -259,8 +258,8 @@ status_t
get_font_style(font_family family, int32 index, font_style *name,
uint16 *face, uint32 *flags)
{
if(!name || !face)
return B_ERROR;
if (!name || !face)
return B_BAD_VALUE;
int32 code;
BPrivate::AppServerLink link;
@ -331,12 +330,10 @@ set_font_cache_info(uint32 id, void *set)
}
//----------------------------------------------------------------------------------------
// BFont Class Definition
//----------------------------------------------------------------------------------------
// #pragma mark -
BFont::BFont(void)
BFont::BFont()
:
// initialise for be_plain_font (avoid circular definition)
fFamilyID(0),
@ -349,56 +346,28 @@ BFont::BFont(void)
fFace(0),
fFlags(0)
{
fHeight.ascent = 7.0;
fHeight.descent = 2.0;
fHeight.leading = 13.0;
fFamilyID = be_plain_font->fFamilyID;
fStyleID = be_plain_font->fStyleID;
fSize = be_plain_font->fSize;
if (be_plain_font != NULL && this != &sPlainFont)
*this = *be_plain_font;
else {
fHeight.ascent = 7.0;
fHeight.descent = 2.0;
fHeight.leading = 13.0;
}
}
BFont::BFont(const BFont &font)
{
fFamilyID = font.fFamilyID;
fStyleID = font.fStyleID;
fSize = font.fSize;
fShear = font.fShear;
fRotation = font.fRotation;
fSpacing = font.fSpacing;
fEncoding = font.fEncoding;
fFace = font.fFace;
fFlags = font.fFlags;
fHeight = font.fHeight;
*this = font;
}
BFont::BFont(const BFont *font)
{
if (font) {
fFamilyID = font->fFamilyID;
fStyleID = font->fStyleID;
fSize = font->fSize;
fShear = font->fShear;
fRotation = font->fRotation;
fSpacing = font->fSpacing;
fEncoding = font->fEncoding;
fFace = font->fFace;
fFlags = font->fFlags;
fHeight = font->fHeight;
} else {
fFamilyID = be_plain_font->fFamilyID;
fStyleID = be_plain_font->fStyleID;
fSize = be_plain_font->fSize;
fShear = be_plain_font->fShear;
fRotation = be_plain_font->fRotation;
fSpacing = be_plain_font->fSpacing;
fEncoding = be_plain_font->fEncoding;
fFace = be_plain_font->fFace;
fFlags = be_plain_font->fFlags;
fHeight = be_plain_font->fHeight;
}
if (font)
*this = *font;
else
*this = *be_plain_font;
}
@ -406,42 +375,30 @@ BFont::BFont(const BFont *font)
\brief Sets the font's family and style all at once
\param family Font family to set
\param style Font style to set
\return B_ERROR if family or style do not exist or if style does not belong to family.
\return B_NAME_NOT_FOUND if family or style do not exist.
*/
status_t
BFont::SetFamilyAndStyle(const font_family family, const font_style style)
{
// R5 version always returns B_OK. That's a problem...
if (!family)
return B_ERROR;
if (family == NULL && style == NULL)
return B_BAD_VALUE;
int32 code;
BPrivate::AppServerLink link;
if (!style) {
// The BeBook states that a NULL style means set only the family
link.StartMessage(AS_SET_FAMILY_NAME);
link.Attach(family, sizeof(font_family));
link.StartMessage(AS_SET_FAMILY_AND_STYLE);
link.AttachString(family);
link.AttachString(style);
link.Attach<uint16>(fFace);
if (link.FlushWithReply(code) != B_OK
|| code != SERVER_TRUE)
return B_ERROR;
link.Read<uint16>(&fFamilyID);
} else {
link.StartMessage(AS_SET_FAMILY_AND_STYLE);
link.Attach(family, sizeof(font_family));
link.Attach(style, sizeof(font_style));
if (link.FlushWithReply(code) != B_OK
|| code != SERVER_TRUE)
return B_ERROR;
link.Read<uint16>(&fFamilyID);
link.Read<uint16>(&fStyleID);
}
int32 status;
if (link.FlushWithReply(status) != B_OK
|| status != B_OK)
return status;
link.Read<uint16>(&fFamilyID);
link.Read<uint16>(&fStyleID);
link.Read<uint16>(&fFace);
return B_OK;
}
@ -577,9 +534,19 @@ BFont::SetFlags(uint32 flags)
void
BFont::GetFamilyAndStyle(font_family *family, font_style *style) const
{
if (!family || !style)
if (family == NULL && style == NULL)
return;
// it's okay to call this function with either family or style set to NULL
font_family familyBuffer;
font_style styleBuffer;
if (family == NULL)
family = &familyBuffer;
if (style == NULL)
style = &styleBuffer;
int32 code;
BPrivate::AppServerLink link;
@ -588,8 +555,12 @@ BFont::GetFamilyAndStyle(font_family *family, font_style *style) const
link.Attach<uint16>(fStyleID);
if (link.FlushWithReply(code) != B_OK
|| code != SERVER_TRUE)
|| code != SERVER_TRUE) {
// the least we can do is to clear the buffers
memset(family, 0, sizeof(font_family));
memset(style, 0, sizeof(font_style));
return;
}
link.Read<font_family>(family);
link.Read<font_style>(style);
@ -599,8 +570,7 @@ BFont::GetFamilyAndStyle(font_family *family, font_style *style) const
uint32
BFont::FamilyAndStyle(void) const
{
uint32 token = (fFamilyID << 16) | fStyleID;
return token;
return (fFamilyID << 16UL) | fStyleID;
}
@ -784,7 +754,7 @@ BFont::GetTunedInfo(int32 index, tuned_font_info *info) const
link.Read<tuned_font_info>(info);
}
// TruncateString
void
BFont::TruncateString(BString *inOut, uint32 mode, float width) const
{
@ -795,7 +765,7 @@ BFont::TruncateString(BString *inOut, uint32 mode, float width) const
GetTruncatedStrings(array, 1, mode, width, inOut);
}
// GetTruncatedStrings
void
BFont::GetTruncatedStrings(const char *stringArray[], int32 numStrings,
uint32 mode, float width, BString resultArray[]) const
@ -818,7 +788,7 @@ BFont::GetTruncatedStrings(const char *stringArray[], int32 numStrings,
}
}
// GetTruncatedStrings
void
BFont::GetTruncatedStrings(const char *stringArray[], int32 numStrings,
uint32 mode, float width, char *resultArray[]) const
@ -842,15 +812,17 @@ BFont::GetTruncatedStrings(const char *stringArray[], int32 numStrings,
}
}
// StringWidth
float
BFont::StringWidth(const char *string) const
{
if (!string)
return 0.0;
int32 length = strlen(string);
float width;
GetStringWidths(&string, &length, 1, &width);
return width;
}
@ -863,6 +835,7 @@ BFont::StringWidth(const char *string, int32 length) const
float width;
GetStringWidths(&string, &length, 1, &width);
return width;
}
@ -908,7 +881,7 @@ void
BFont::GetEscapements(const char charArray[], int32 numChars, escapement_delta *delta,
float escapementArray[]) const
{
if (!charArray || numChars < 1 || !escapementArray)
if (!charArray || numChars < 1 || !escapementArray)
return;
// NOTE: The R5 implementation crashes if delta == NULL!
@ -953,7 +926,7 @@ void
BFont::GetEscapements(const char charArray[], int32 numChars, escapement_delta *delta,
BPoint escapementArray[], BPoint offsetArray[]) const
{
if (!charArray || numChars<1 || !escapementArray)
if (!charArray || numChars < 1 || !escapementArray)
return;
int32 code;

View File

@ -36,13 +36,14 @@ FTC_Manager ftmanager;
\param face FreeType handle for the font file after it is loaded - it will be kept open until the FontStyle is destroied
*/
FontStyle::FontStyle(const char *filepath, FT_Face face)
: fFTFace(face),
fFontFamily(NULL),
fName(face->style_name),
fPath(filepath),
fBounds(0, 0, 0, 0),
fID(0),
fFace(TranslateStyleToFace(face->style_name))
:
fFTFace(face),
fFontFamily(NULL),
fName(face->style_name),
fPath(filepath),
fBounds(0, 0, 0, 0),
fID(0),
fFace(_TranslateStyleToFace(face->style_name))
{
// cachedface = new CachedFaceRec;
// cachedface->file_path = filepath;
@ -57,6 +58,7 @@ FontStyle::FontStyle(const char *filepath, FT_Face face)
fHeight.units_per_em = face->units_per_EM;
}
/*!
\brief Destructor
@ -73,6 +75,7 @@ FontStyle::~FontStyle()
// FT_Done_Face(fFTFace);
}
/*!
\brief Returns the name of the style as a string
\return The style's name
@ -83,6 +86,7 @@ FontStyle::Name() const
return fName.String();
}
font_height
FontStyle::GetHeight(const float &size) const
{
@ -99,29 +103,32 @@ FontStyle::GetHeight(const float &size) const
return fh;
}
/*!
\brief Returns the path to the style's font file
\return The style's font file path
*/
const char*
FontStyle::GetPath() const
FontStyle::Path() const
{
return fPath.String();
}
int32
FontStyle::GetFlags() const
FontStyle::Flags() const
{
int32 flags=0;
if(IsFixedWidth())
flags|=B_IS_FIXED;
if(TunedCount()>0)
flags|=B_HAS_TUNED_FONT;
int32 flags = 0;
if (IsFixedWidth())
flags |= B_IS_FIXED;
if (TunedCount() > 0)
flags |= B_HAS_TUNED_FONT;
return flags;
}
/*!
\brief Converts an ASCII character to Unicode for the style
\param c An ASCII character
@ -131,7 +138,8 @@ FontStyle::GetFlags() const
// 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)
int16
FontStyle::ConvertToUnicode(uint16 c)
{
FT_Face f;
if(FTC_Manager_LookupFace(ftmanager,(FTC_FaceID)cachedface,&f)!=0)
@ -142,34 +150,40 @@ int16 FontStyle::ConvertToUnicode(uint16 c)
*/
uint16
FontStyle::TranslateStyleToFace(const char *name) const
FontStyle::_TranslateStyleToFace(const char *name) const
{
if(!name)
if (name == NULL)
return 0;
BString str(name);
if(str.IFindFirst("bold")!=B_ERROR)
return B_BOLD_FACE;
if(str.IFindFirst("italic")!=B_ERROR)
return B_ITALIC_FACE;
if(str.IFindFirst("oblique")!=B_ERROR)
return B_ITALIC_FACE;
return B_REGULAR_FACE;
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
*/
FontFamily::FontFamily(const char *namestr, const uint16 &index)
FontFamily::FontFamily(const char *name, const uint16 &index)
{
fName = namestr;
fName = name;
fID = index;
// will stay uninitialized until needed
fFlags = -1;
}
@ -188,6 +202,7 @@ FontFamily::~FontFamily()
delete (FontStyle*)fStyles.ItemAt(i);
}
/*!
\brief Returns the name of the family
\return The family's name
@ -198,6 +213,7 @@ FontFamily::Name() const
return fName.String();
}
/*!
\brief Adds the style to the family
\param face FreeType face handle used to obtain info about the font
@ -212,57 +228,52 @@ FontFamily::AddStyle(FontStyle *style)
// Don't add if it already is in the family.
int32 count = fStyles.CountItems();
for(int32 i = 0; i < count; i++) {
for (int32 i = 0; i < count; i++) {
item = (FontStyle*)fStyles.ItemAt(i);
if (item->fName == style->fName)
if (item->Name() == style->Name())
return false;
}
style->fFontFamily = this;
style->_SetFontFamily(this);
if (fStyles.CountItems() > 0) {
item = (FontStyle*)fStyles.ItemAt(fStyles.CountItems() - 1);
style->fID = item->fID + 1;
style->_SetID(item->ID() + 1);
} else {
style->fID = 0;
style->_SetID(0);
}
fStyles.AddItem(style);
AddDependent();
// force a refresh if a request for font flags is needed
fFlags=-1;
fFlags = -1;
return true;
}
/*!
\brief Removes a style from the family and deletes it
\param style Name of the style to be removed from the family
*/
void
FontFamily::RemoveStyle(const char* style)
FontFamily::RemoveStyle(const char* styleName)
{
int32 count = fStyles.CountItems();
if (!style || count < 1)
FontStyle *style = GetStyle(styleName);
if (style == NULL)
return;
FontStyle *fs;
for (int32 i = 0; i < count; i++) {
fs = (FontStyle*)fStyles.ItemAt(i);
if (fs && fs->fName.Compare(style) == 0) {
if (fStyles.RemoveItem((void*)fs)) {
delete fs;
RemoveDependent();
// force a refresh if a request for font flags is needed
fFlags = -1;
break;
}
}
}
fStyles.RemoveItem(style);
delete style;
RemoveDependent();
// force a refresh if a request for font flags is needed
fFlags = -1;
}
/*!
\brief Removes a style from the family. The caller is responsible for freeing the object
\param style The style to be removed from the family
@ -270,14 +281,15 @@ FontFamily::RemoveStyle(const char* style)
void
FontFamily::RemoveStyle(FontStyle* style)
{
if (fStyles.RemoveItem((void*)style)) {
if (fStyles.RemoveItem(style)) {
RemoveDependent();
// force a refresh if a request for font flags is needed
fFlags = -1;
}
}
/*!
\brief Returns the number of styles in the family
\return The number of styles in the family
@ -288,39 +300,31 @@ FontFamily::CountStyles() const
return fStyles.CountItems();
}
/*!
\brief Determines whether the style belongs to the family
\param style Name of the style being checked
\return True if it belongs, false if not
*/
bool
FontFamily::HasStyle(const char *style) const
FontFamily::HasStyle(const char *styleName) const
{
int32 count = fStyles.CountItems();
if (!style || count < 1)
return false;
FontStyle *fs;
for (int32 i = 0; i < count; i++) {
fs = (FontStyle*)fStyles.ItemAt(i);
if( fs && fs->fName.Compare(style) == 0)
return true;
}
return false;
return GetStyle(styleName) != NULL;
}
/*!
\brief Returns the name of a style in the family
\param index list index of the style to be found
\return name of the style or NULL if the index is not valid
*/
FontStyle*
FontFamily::GetStyle(int32 index) const
FontFamily::StyleAt(int32 index) const
{
return (FontStyle*)fStyles.ItemAt(index);
return fStyles.ItemAt(index);
}
/*!
\brief Get the FontStyle object for the name given
\param style Name of the style to be obtained
@ -329,27 +333,54 @@ FontFamily::GetStyle(int32 index) const
The object returned belongs to the family and must not be deleted.
*/
FontStyle*
FontFamily::GetStyle(const char *style) const
FontFamily::GetStyle(const char *styleName) const
{
int32 count=fStyles.CountItems();
if (!style || count < 1)
int32 count = fStyles.CountItems();
if (!styleName || count < 1)
return NULL;
FontStyle *fs;
for (int32 i = 0; i < count; i++) {
fs = (FontStyle*)fStyles.ItemAt(i);
if (fs && fs->fName.Compare(style) == 0)
return fs;
FontStyle *style = fStyles.ItemAt(i);
if (!strcmp(style->Name(), styleName))
return style;
}
return NULL;
}
FontStyle*
FontFamily::GetStyleWithID(uint16 id) const
{
for (int32 i = 0; i < fStyles.CountItems(); i++) {
FontStyle* style = fStyles.ItemAt(i);
if (style->ID() == id)
return style;
}
return NULL;
}
FontStyle*
FontFamily::GetStyleWithFace(uint16 face) const
{
for (int32 i = 0; i < fStyles.CountItems(); i++) {
FontStyle* style = fStyles.ItemAt(i);
if (style->Face() == face)
return style;
}
return NULL;
}
int32
FontFamily::GetFlags()
FontFamily::Flags()
{
if (fFlags == -1) {
fFlags = 0;
for (int32 i = 0; i < fStyles.CountItems(); i++) {
FontStyle* style = (FontStyle*)fStyles.ItemAt(i);
if (style) {

View File

@ -123,7 +123,7 @@ FontServer::GetFamilyName(uint16 id) const
{
for (int32 i = 0; i < fFamilies.CountItems(); i++) {
FontFamily* family = (FontFamily*)fFamilies.ItemAt(i);
if (family && family->GetID() == id)
if (family && family->ID() == id)
return family->Name();
}
@ -146,12 +146,8 @@ FontStyle*
FontServer::GetStyle(const char* familyName, uint16 id) const
{
FontFamily* family = GetFamily(familyName);
for (int32 i = 0; i < family->CountStyles(); i++) {
FontStyle* style = family->GetStyle(i);
if (style && style->GetID() == id)
return style;
}
if (family != NULL)
return family->GetStyleWithID(id);
return NULL;
}
@ -167,7 +163,7 @@ FontServer::GetStyle(const char* familyName, uint16 id) const
FontFamily*
FontServer::GetFamily(const char* name) const
{
if (!fInit)
if (!fInit || name == NULL)
return NULL;
int32 count = fFamilies.CountItems();
@ -407,12 +403,16 @@ FontServer::SaveList(void)
\return The FontStyle having those attributes or NULL if not available
*/
FontStyle*
FontServer::GetStyle(const char* familyName, const char* styleName)
FontServer::GetStyle(const char* familyName, const char* styleName, uint16 face)
{
FontFamily* family = GetFamily(familyName);
if (family)
if (family) {
if (styleName == NULL) {
// try to get from face
return family->GetStyleWithFace(face);
}
return family->GetStyle(styleName);
}
return NULL;
}
@ -425,23 +425,22 @@ FontServer::GetStyle(const char* familyName, const char* styleName)
\return The FontStyle having those attributes or NULL if not available
*/
FontStyle*
FontServer::GetStyle(const uint16& familyID, const uint16& styleID)
FontServer::GetStyle(uint16 familyID, uint16 styleID)
{
FontFamily *family = GetFamily(familyID);
if (family)
return family->GetStyle(styleID);
return family->GetStyleWithID(styleID);
return NULL;
}
FontFamily*
FontServer::GetFamily(const uint16& familyID) const
FontServer::GetFamily(uint16 familyID) const
{
for (int32 i = 0; i < fFamilies.CountItems(); i++) {
FontFamily *family = (FontFamily*)fFamilies.ItemAt(i);
if (family->GetID() == familyID)
if (family->ID() == familyID)
return family;
}

View File

@ -1174,7 +1174,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
fam[sizeof(font_family) - 1] = 0;
fLink.StartMessage(SERVER_TRUE);
fLink.Attach(fam, sizeof(font_family));
fLink.Attach<uint32>(ffamily->GetFlags());
fLink.Attach<uint32>(ffamily->Flags());
} else
fLink.StartMessage(SERVER_FALSE);
@ -1208,8 +1208,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
style[sizeof(font_style) - 1] = 0;
fLink.StartMessage(SERVER_TRUE);
fLink.Attach(style, sizeof(font_style));
fLink.Attach<uint32>(fstyle->GetFace());
fLink.Attach<uint32>(fstyle->GetFlags());
fLink.Attach<uint32>(fstyle->Face());
fLink.Attach<uint32>(fstyle->Flags());
} else
fLink.StartMessage(SERVER_FALSE);
@ -1227,27 +1227,27 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
// Returns:
// 1) font_family The name of the font family
// 2) font_style - name of the style
uint16 famid, styid;
font_family fam;
font_style sty;
link.Read<uint16>(&famid);
link.Read<uint16>(&styid);
uint16 familyID, styleID;
link.Read<uint16>(&familyID);
link.Read<uint16>(&styleID);
gFontServer->Lock();
FontStyle *fstyle = gFontServer->GetStyle(famid, styid);
if (fstyle) {
strncpy(fam, fstyle->Family()->Name(), sizeof(font_family) - 1);
strncpy(sty, fstyle->Name(), sizeof(font_style) - 1);
fam[sizeof(font_family) - 1] = 0;
sty[sizeof(font_style) - 1] = 0;
FontStyle *fontStyle = gFontServer->GetStyle(familyID, styleID);
if (fontStyle != NULL) {
font_family family;
font_style style;
fLink.StartMessage(SERVER_TRUE);
fLink.Attach(fam, sizeof(font_family));
fLink.Attach(sty, sizeof(font_style));
strncpy(family, fontStyle->Family()->Name(), sizeof(font_family) - 1);
family[sizeof(font_family) - 1] = 0;
strncpy(style, fontStyle->Name(), sizeof(font_style) - 1);
style[sizeof(font_style) - 1] = 0;
fLink.StartMessage(B_OK);
fLink.Attach(family, sizeof(font_family));
fLink.Attach(style, sizeof(font_style));
} else
fLink.StartMessage(SERVER_FALSE);
fLink.StartMessage(B_BAD_VALUE);
fLink.Flush();
gFontServer->Unlock();
break;
@ -1319,7 +1319,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
float widthArray[numStrings];
int32 lengthArray[numStrings];
char *stringArray[numStrings];
for(int32 i=0; i<numStrings; i++) {
for (int32 i = 0; i < numStrings; i++) {
link.Read<int32>(&lengthArray[i]);
stringArray[i] = new char[lengthArray[i]];
link.ReadString(&stringArray[i]);
@ -1333,7 +1333,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
font.SetSize(size);
font.SetSpacing(spacing);
for (int32 i=0; i<numStrings; i++)
for (int32 i = 0; i < numStrings; i++)
if (!stringArray[i] || lengthArray[i] <= 0)
widthArray[i] = 0.0;
else
@ -1349,7 +1349,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
fLink.StartMessage(SERVER_FALSE);
fLink.Flush();
for(int32 i=0; i<numStrings; i++) {
for (int32 i = 0; i < numStrings; i++) {
delete[] stringArray[i];
}
break;
@ -1437,30 +1437,6 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
gFontServer->Unlock();
break;
}
case AS_SET_FAMILY_NAME:
{
FTRACE(("ServerApp %s: AS_SET_FAMILY_NAME\n", Signature()));
// Attached Data:
// 1) font_family - name of font family to use
// Returns:
// 1) uint16 - family ID
font_family fam;
link.Read(fam, sizeof(font_family));
gFontServer->Lock();
FontFamily *ffam = gFontServer->GetFamily(fam);
if (ffam) {
fLink.StartMessage(SERVER_TRUE);
fLink.Attach<uint16>(ffam->GetID());
} else
fLink.StartMessage(SERVER_FALSE);
fLink.Flush();
gFontServer->Unlock();
break;
}
case AS_SET_FAMILY_AND_STYLE:
{
FTRACE(("ServerApp %s: AS_SET_FAMILY_AND_STYLE\n",
@ -1468,27 +1444,35 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
// Attached Data:
// 1) font_family - name of font family to use
// 2) font_style - name of style in family
// 3) face - the font's current face
// Returns:
// 1) uint16 - family ID
// 2) uint16 - style ID
// 3) uint16 - face
font_family fam;
font_style sty;
link.Read(fam, sizeof(font_family));
link.Read(sty, sizeof(font_style));
gFontServer->Lock();
FontStyle *fstyle = gFontServer->GetStyle(fam, sty);
if (fstyle) {
fLink.StartMessage(SERVER_TRUE);
fLink.Attach<uint16>(fstyle->Family()->GetID());
fLink.Attach<uint16>(fstyle->GetID());
font_family family;
font_style style;
uint16 face;
if (link.ReadString(family, sizeof(font_family)) == B_OK
&& link.ReadString(style, sizeof(font_style)) == B_OK
&& link.Read<uint16>(&face) == B_OK) {
// get the font and return IDs and face
gFontServer->Lock();
FontStyle *fontStyle = gFontServer->GetStyle(family[0] ? family : NULL,
style[0] ? style : NULL, face);
if (fontStyle != NULL) {
fLink.StartMessage(B_OK);
fLink.Attach<uint16>(fontStyle->Family()->ID());
fLink.Attach<uint16>(fontStyle->ID());
fLink.Attach<uint16>(fontStyle->Face());
} else
fLink.StartMessage(B_NAME_NOT_FOUND);
gFontServer->Unlock();
} else
fLink.StartMessage(SERVER_FALSE);
fLink.StartMessage(B_BAD_VALUE);
fLink.Flush();
gFontServer->Unlock();
break;
}
case AS_SET_FAMILY_AND_STYLE_FROM_ID:

View File

@ -6,7 +6,7 @@ if $(TARGET_PLATFORM) != haiku {
}
UseLibraryHeaders agg ;
UsePrivateHeaders app interface [ FDirName servers app ] ;
UsePrivateHeaders app interface shared [ FDirName servers app ] ;
UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing Painter drawing_modes ] ;
UseHeaders [ FDirName $(HAIKU_TOP) src servers app drawing Painter font_support ] ;
UseFreeTypeHeaders ;