* A ServerFont is now always valid, bye-bye ServerFont::InitCheck().

* The FontFamily is no longer reference counting itself.
* SharedObject is now more useful and destructs itself when unused.
* Fixed FontStyle::GetHeight()/ServerFont::GetHeight() semantics.
* Simplified ServerFont constructors.
* Removed wrong function descriptions.
* FontStyleHeight is no longer used: the FontStyle is calculating the
  base font height on construction - this reduces the resolution a bit,
  but it's hopefully not causing any troubles (doesn't look like it,
  at least).
* A FontStyle now removes itself from its family on destruction.
* More cleanup, removed unused stuff like FontStyleHeight.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14657 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2005-11-03 13:10:28 +00:00
parent 8000593677
commit 8365d9ecd2
10 changed files with 228 additions and 278 deletions
+24 -48
View File
@@ -38,27 +38,6 @@ enum font_format {
FONT_WINFONT, FONT_WINFONT,
}; };
/*
//! data structure used by the FreeType cache manager
typedef struct CachedFaceRec_
{
BString file_path;
int face_index;
} CachedFaceRec, *CachedFace;
*/
/*!
\brief Private structure to store font height values
Units provided by FT2 are in font units, so they are stored in the style as
such. Each value must be multiplied by the point size to determine size in pixels
*/
typedef struct {
FT_Short ascent;
FT_Short descent;
FT_Short leading;
FT_UShort units_per_em;
} FontStyleHeight;
/*! /*!
\class FontStyle FontFamily.h \class FontStyle FontFamily.h
@@ -78,53 +57,54 @@ class FontStyle : public SharedObject, public BLocker {
\return true if fixed, false if not \return true if fixed, false if not
*/ */
bool IsFixedWidth() const bool IsFixedWidth() const
{ return fFTFace->face_flags & FT_FACE_FLAG_FIXED_WIDTH; } { return fFreeTypeFace->face_flags & FT_FACE_FLAG_FIXED_WIDTH; }
/*! /*!
\fn bool FontStyle::IsScalable(void) \fn bool FontStyle::IsScalable(void)
\brief Determines whether the font can be scaled to any size \brief Determines whether the font can be scaled to any size
\return true if scalable, false if not \return true if scalable, false if not
*/ */
bool IsScalable() const bool IsScalable() const
{ return fFTFace->face_flags & FT_FACE_FLAG_SCALABLE; } { return fFreeTypeFace->face_flags & FT_FACE_FLAG_SCALABLE; }
/*! /*!
\fn bool FontStyle::HasKerning(void) \fn bool FontStyle::HasKerning(void)
\brief Determines whether the font has kerning information \brief Determines whether the font has kerning information
\return true if kerning info is available, false if not \return true if kerning info is available, false if not
*/ */
bool HasKerning() const bool HasKerning() const
{ return fFTFace->face_flags & FT_FACE_FLAG_KERNING; } { return fFreeTypeFace->face_flags & FT_FACE_FLAG_KERNING; }
/*! /*!
\fn bool FontStyle::HasTuned(void) \fn bool FontStyle::HasTuned(void)
\brief Determines whether the font contains strikes \brief Determines whether the font contains strikes
\return true if it has strikes included, false if not \return true if it has strikes included, false if not
*/ */
bool HasTuned() const bool HasTuned() const
{ return fFTFace->num_fixed_sizes > 0; } { return fFreeTypeFace->num_fixed_sizes > 0; }
/*! /*!
\fn bool FontStyle::TunedCount(void) \fn bool FontStyle::TunedCount(void)
\brief Returns the number of strikes the style contains \brief Returns the number of strikes the style contains
\return The number of strikes the style contains \return The number of strikes the style contains
*/ */
int32 TunedCount() const int32 TunedCount() const
{ return fFTFace->num_fixed_sizes; } { return fFreeTypeFace->num_fixed_sizes; }
/*! /*!
\fn bool FontStyle::GlyphCount(void) \fn bool FontStyle::GlyphCount(void)
\brief Returns the number of glyphs in the style \brief Returns the number of glyphs in the style
\return The number of glyphs the style contains \return The number of glyphs the style contains
*/ */
uint16 GlyphCount() const uint16 GlyphCount() const
{ return fFTFace->num_glyphs; } { return fFreeTypeFace->num_glyphs; }
/*! /*!
\fn bool FontStyle::CharMapCount(void) \fn bool FontStyle::CharMapCount(void)
\brief Returns the number of character maps the style contains \brief Returns the number of character maps the style contains
\return The number of character maps the style contains \return The number of character maps the style contains
*/ */
uint16 CharMapCount() const uint16 CharMapCount() const
{ return fFTFace->num_charmaps; } { return fFreeTypeFace->num_charmaps; }
const char* Name() const; const char* Name() const
{ return fName.String(); }
FontFamily* Family() const FontFamily* Family() const
{ return fFontFamily; } { return fFamily; }
uint16 ID() const uint16 ID() const
{ return fID; } { return fID; }
int32 Flags() const; int32 Flags() const;
@@ -134,14 +114,16 @@ class FontStyle : public SharedObject, public BLocker {
uint16 PreservedFace(uint16) const; uint16 PreservedFace(uint16) const;
const char* Path() const; const char* Path() const;
font_height GetHeight(const float& size) const; void GetHeight(float size, font_height &heigth) const;
font_direction Direction() const font_direction Direction() const
{ return B_FONT_LEFT_TO_RIGHT; } { return B_FONT_LEFT_TO_RIGHT; }
font_file_format FileFormat() const font_file_format FileFormat() const
{ return B_TRUETYPE_WINDOWS; } { return B_TRUETYPE_WINDOWS; }
FT_Face GetFTFace() const FT_Face FreeTypeFace() const
{ return fFTFace; } { return fFreeTypeFace; }
status_t UpdateFace(FT_Face face);
// TODO: Re-enable when I understand how the FT2 Cache system changed from // TODO: Re-enable when I understand how the FT2 Cache system changed from
// 2.1.4 to 2.1.8 // 2.1.4 to 2.1.8
@@ -150,26 +132,20 @@ class FontStyle : public SharedObject, public BLocker {
private: private:
friend class FontFamily; friend class FontFamily;
uint16 _TranslateStyleToFace(const char *name) const; uint16 _TranslateStyleToFace(const char *name) const;
void _SetFontFamily(FontFamily* family) void _SetFontFamily(FontFamily* family, uint16 id);
{ fFontFamily = family; }
void _SetID(uint16 id)
{ fID = id; }
private: private:
FT_Face fFTFace; FT_Face fFreeTypeFace;
// CachedFace cachedface;
FontFamily* fFontFamily;
BString fName; BString fName;
BString fPath; BString fPath;
FontFamily* fFamily;
uint16 fID;
BRect fBounds; BRect fBounds;
uint16 fID; font_height fHeight;
uint16 fFace; uint16 fFace;
FontStyleHeight fHeight;
}; };
/*! /*!
@@ -179,7 +155,7 @@ class FontStyle : public SharedObject, public BLocker {
FontFamily objects bring together many styles of the same face, such as FontFamily objects bring together many styles of the same face, such as
Arial Roman, Arial Italic, Arial Bold, etc. Arial Roman, Arial Italic, Arial Bold, etc.
*/ */
class FontFamily : public SharedObject { class FontFamily {
public: public:
FontFamily(const char* name, uint16 id); FontFamily(const char* name, uint16 id);
virtual ~FontFamily(); virtual ~FontFamily();
@@ -187,8 +163,8 @@ class FontFamily : public SharedObject {
const char* Name() const; const char* Name() const;
bool AddStyle(FontStyle* style); bool AddStyle(FontStyle* style);
void RemoveStyle(const char* style); bool RemoveStyle(const char* style);
void RemoveStyle(FontStyle* style); bool RemoveStyle(FontStyle* style);
FontStyle* GetStyle(const char* style) const; FontStyle* GetStyle(const char* style) const;
FontStyle* GetStyleMatchingFace(uint16 face) const; FontStyle* GetStyleMatchingFace(uint16 face) const;
+7 -12
View File
@@ -3,13 +3,13 @@
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* DarkWyrm <[email protected]> * DarkWyrm <[email protected]>
* Jérôme Duval, [email protected] * Jérôme Duval, [email protected]
*/ */
#ifndef SERVERFONT_H_ #ifndef SERVERFONT_H_
#define SERVERFONT_H_ #define SERVERFONT_H_
#include <Font.h> #include <Font.h>
#include <Rect.h> #include <Rect.h>
@@ -18,10 +18,11 @@
class BShape; class BShape;
class BString; class BString;
class ServerFont { class ServerFont {
public: public:
ServerFont(); ServerFont();
ServerFont(FontStyle* style, ServerFont(FontStyle& style,
float size = 12.0, float size = 12.0,
float fRotation = 0.0, float fRotation = 0.0,
float fShear = 90.0, float fShear = 90.0,
@@ -30,13 +31,7 @@ class ServerFont {
ServerFont(const ServerFont& font); ServerFont(const ServerFont& font);
virtual ~ServerFont(); virtual ~ServerFont();
// TODO: make more advanced...
status_t InitCheck() const
{ return fStyle ? B_OK : B_NO_INIT; }
ServerFont &operator=(const ServerFont& font); ServerFont &operator=(const ServerFont& font);
font_direction Direction() const font_direction Direction() const
{ return fDirection; } { return fDirection; }
@@ -145,10 +140,10 @@ class ServerFont {
void Unlock() const { fStyle->Unlock(); } void Unlock() const { fStyle->Unlock(); }
FT_Face GetFTFace() const FT_Face GetFTFace() const
{ return fStyle->GetFTFace(); }; { return fStyle->FreeTypeFace(); };
BRect BoundingBox(); BRect BoundingBox();
void Height(font_height* fh) const; void GetHeight(font_height& height) const;
void TruncateString(BString* inOut, void TruncateString(BString* inOut,
uint32 mode, uint32 mode,
+40 -46
View File
@@ -1,37 +1,18 @@
//------------------------------------------------------------------------------ /*
// Copyright (c) 2001-2002, Haiku, Inc. * Copyright 2001-2005, Haiku.
// * Distributed under the terms of the MIT License.
// Permission is hereby granted, free of charge, to any person obtaining a *
// copy of this software and associated documentation files (the "Software"), * Authors:
// to deal in the Software without restriction, including without limitation * DarkWyrm <[email protected]>
// the rights to use, copy, modify, merge, publish, distribute, sublicense, * Axel Dörfler, [email protected]
// 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: #ifndef SHARED_OBJECT_H
// #define SHARED_OBJECT_H
// 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: SharedObject.h
// Author: DarkWyrm <[email protected]>
// Description: This class is used as a base class for other objects which
// must be shared. By using this, objects which depend on its
// existence can be somewhat sure that the shared object will
// not be deleted until nothing depends on it.
//
//------------------------------------------------------------------------------
#ifndef SHAREDOBJ_H_
#define SHAREDOBJ_H_
#include <SupportDefs.h> #include <SupportDefs.h>
/*! /*!
\class SharedObject SharedObject.h \class SharedObject SharedObject.h
\brief Base class for shared objects \brief Base class for shared objects
@@ -41,21 +22,34 @@
needs it. How the dependency tracking is done largely depends on the child class. needs it. How the dependency tracking is done largely depends on the child class.
*/ */
class SharedObject { class SharedObject {
public: public:
SharedObject() SharedObject()
: fReferenceCount(0) : fReferenceCount(1) {}
{} virtual ~SharedObject() {}
virtual ~SharedObject()
{}
virtual void AddDependent() inline void Acquire();
{ fReferenceCount++; } inline bool Release();
virtual void RemoveDependent()
{ fReferenceCount--; } private:
virtual bool HasDependents() int32 fReferenceCount;
{ return (fReferenceCount > 0); }
private:
uint32 fReferenceCount;
}; };
#endif
inline void
SharedObject::Acquire()
{
atomic_add(&fReferenceCount, 1);
}
inline bool
SharedObject::Release()
{
if (atomic_add(&fReferenceCount, -1) == 1) {
delete this;
return true;
}
return false;
}
#endif /* SHARED_OBJECT_H */
+11 -8
View File
@@ -343,11 +343,12 @@ DefaultDecorator::_DoLayout()
// In this case the text and close/zoom rects // In this case the text and close/zoom rects
fTextOffset = (_look == B_FLOATING_WINDOW_LOOK) ? 10 : 18; fTextOffset = (_look == B_FLOATING_WINDOW_LOOK) ? 10 : 18;
font_height fh; font_height fontHeight;
_drawdata.Font().Height(&fh); _drawdata.Font().GetHeight(fontHeight);
_tabrect.Set(_frame.left - fBorderWidth, _tabrect.Set(_frame.left - fBorderWidth,
_frame.top - fBorderWidth - ceilf(fh.ascent + fh.descent + 7.0), _frame.top - fBorderWidth
- ceilf(fontHeight.ascent + fontHeight.descent + 7.0),
((_frame.right - _frame.left) < 35.0 ? ((_frame.right - _frame.left) < 35.0 ?
_frame.left + 35.0 : _frame.right) + fBorderWidth, _frame.left + 35.0 : _frame.right) + fBorderWidth,
_frame.top - fBorderWidth); _frame.top - fBorderWidth);
@@ -628,13 +629,15 @@ DefaultDecorator::_DrawTitle(BRect r)
_drawdata.SetLowColor(fTabColor); _drawdata.SetLowColor(fTabColor);
// figure out position of text // figure out position of text
font_height fh; font_height fontHeight;
_drawdata.Font().Height(&fh); _drawdata.Font().GetHeight(fontHeight);
BPoint titlePos; BPoint titlePos;
titlePos.x = _closerect.IsValid() ? _closerect.right + fTextOffset : _tabrect.left + fTextOffset; titlePos.x = _closerect.IsValid() ? _closerect.right + fTextOffset
titlePos.y = floorf(((_tabrect.top + 2.0) + _tabrect.bottom + fh.ascent + fh.descent) / 2.0 - fh.descent + 0.5); : _tabrect.left + fTextOffset;
titlePos.y = floorf(((_tabrect.top + 2.0) + _tabrect.bottom + fontHeight.ascent
+ fontHeight.descent) / 2.0 - fontHeight.descent + 0.5);
_driver->DrawString(fTruncatedTitle.String(), fTruncatedTitleLength, titlePos, &_drawdata); _driver->DrawString(fTruncatedTitle.String(), fTruncatedTitleLength, titlePos, &_drawdata);
} }
+79 -71
View File
@@ -12,6 +12,8 @@
#include "FontFamily.h" #include "FontFamily.h"
#include "ServerFont.h" #include "ServerFont.h"
#include "FontManager.h"
#include FT_CACHE_H #include FT_CACHE_H
@@ -25,72 +27,46 @@ const int32 kInvalidFamilyFlags = -1;
*/ */
FontStyle::FontStyle(const char *path, FT_Face face) FontStyle::FontStyle(const char *path, FT_Face face)
: BLocker(face->style_name), : BLocker(face->style_name),
fFTFace(face), fFreeTypeFace(face),
fFontFamily(NULL),
fName(face->style_name), fName(face->style_name),
fPath(path), fPath(path),
fBounds(0, 0, 0, 0), fFamily(NULL),
fID(0), fID(0),
fBounds(0, 0, 0, 0),
fFace(_TranslateStyleToFace(face->style_name)) fFace(_TranslateStyleToFace(face->style_name))
{ {
fName.Truncate(B_FONT_STYLE_LENGTH); fName.Truncate(B_FONT_STYLE_LENGTH);
// make sure this style can be found using the Be API // make sure this style can be found using the Be API
// cachedface = new CachedFaceRec; fHeight.ascent = (double)face->ascender / face->units_per_EM;
// cachedface->file_path = filepath; fHeight.descent = (double)-face->descender / face->units_per_EM;
// FT2's descent numbers are negative. Be's is positive
fHeight.ascent = face->ascender;
// FT2's descent numbers are negative. Be's is positive
fHeight.descent = -face->descender;
// FT2 doesn't provide a linegap, but according to the docs, we can // FT2 doesn't provide a linegap, but according to the docs, we can
// calculate it because height = ascending + descending + leading // calculate it because height = ascending + descending + leading
fHeight.leading = face->height - (fHeight.ascent + fHeight.descent); fHeight.leading = (double)(face->height - face->ascender + face->descender)
fHeight.units_per_em = face->units_per_EM; / face->units_per_EM;
} }
/*!
\brief Destructor
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() FontStyle::~FontStyle()
{ {
// TODO: what was the purpose of this? // make sure the font server is ours
// delete cachedface; if (fFamily != NULL && gFontManager->Lock()) {
FT_Done_Face(fFTFace); fFamily->RemoveStyle(this);
gFontManager->Unlock();
}
FT_Done_Face(fFreeTypeFace);
} }
/*! void
\brief Returns the name of the style as a string FontStyle::GetHeight(float size, font_height& height) const
\return The style's name
*/
const char*
FontStyle::Name() const
{ {
return fName.String(); height.ascent = fHeight.ascent * size;
} height.descent = fHeight.descent * size;
height.leading = fHeight.leading * size;
font_height
FontStyle::GetHeight(const float &size) const
{
font_height fh = { 0, 0, 0 };
// font units are 26.6 format, so we get REALLY big numbers if
// we don't do some shifting.
// TODO: As it looks like that the "units_per_em" don't change
// for the lifetime of FontStyle, can't we apply these
// conversions in the constructor and get rid of "units_per_em" ?
fh.ascent = (fHeight.ascent * size) / fHeight.units_per_em;
fh.descent = (fHeight.descent * size) / fHeight.units_per_em;
fh.leading = (fHeight.leading * size) / fHeight.units_per_em;
return fh;
} }
@@ -140,6 +116,28 @@ FontStyle::PreservedFace(uint16 face) const
} }
status_t
FontStyle::UpdateFace(FT_Face face)
{
if (!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 \brief Converts an ASCII character to Unicode for the style
\param c An ASCII character \param c An ASCII character
@@ -160,6 +158,15 @@ FontStyle::ConvertToUnicode(uint16 c)
} }
*/ */
void
FontStyle::_SetFontFamily(FontFamily* family, uint16 id)
{
fFamily = family;
fID = id;
}
uint16 uint16
FontStyle::_TranslateStyleToFace(const char *name) const FontStyle::_TranslateStyleToFace(const char *name) const
{ {
@@ -245,11 +252,8 @@ FontFamily::AddStyle(FontStyle *style)
return false; return false;
} }
style->_SetFontFamily(this); style->_SetFontFamily(this, fNextID++);
style->_SetID(fNextID++);
fStyles.AddItem(style); fStyles.AddItem(style);
AddDependent();
// force a refresh if a request for font flags is needed // force a refresh if a request for font flags is needed
fFlags = kInvalidFamilyFlags; fFlags = kInvalidFamilyFlags;
@@ -258,40 +262,44 @@ FontFamily::AddStyle(FontStyle *style)
} }
/*! bool
\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* styleName) FontFamily::RemoveStyle(const char* styleName)
{ {
FontStyle *style = GetStyle(styleName); FontStyle *style = GetStyle(styleName);
if (style == NULL) if (style != NULL)
return; return RemoveStyle(style);
fStyles.RemoveItem(style); return false;
delete style;
RemoveDependent();
// force a refresh if a request for font flags is needed
fFlags = kInvalidFamilyFlags;
} }
/*! /*!
\brief Removes a style from the family. The caller is responsible for freeing the object \brief Removes a style from the family.
The font family may be deleted during this call - the object might not
be valid anymore after this call.
The font style will not be altered.
\param style The style to be removed from the family \param style The style to be removed from the family
*/ */
void bool
FontFamily::RemoveStyle(FontStyle* style) FontFamily::RemoveStyle(FontStyle* style)
{ {
if (fStyles.RemoveItem(style)) { if (!gFontManager->IsLocked()) {
RemoveDependent(); debugger("FontFamily::RemoveStyle() called without having the font manager locked!");
return false;
// force a refresh if a request for font flags is needed
fFlags = kInvalidFamilyFlags;
} }
if (!fStyles.RemoveItem(style))
return false;
// force a refresh if a request for font flags is needed
fFlags = kInvalidFamilyFlags;
if (CountStyles() == 0)
delete this;
return true;
} }
+3 -3
View File
@@ -432,7 +432,7 @@ FontManager::SetSystemPlain(const char* familyName, const char* styleName, float
return false; return false;
delete fPlain; delete fPlain;
fPlain = new ServerFont(style, size); fPlain = new ServerFont(*style, size);
return true; return true;
} }
@@ -454,7 +454,7 @@ FontManager::SetSystemBold(const char* familyName, const char* styleName, float
return false; return false;
delete fBold; delete fBold;
fBold = new ServerFont(style, size); fBold = new ServerFont(*style, size);
return true; return true;
} }
@@ -476,7 +476,7 @@ FontManager::SetSystemFixed(const char* familyName, const char* styleName, float
return false; return false;
delete fFixed; delete fFixed;
fFixed = new ServerFont(style, size); fFixed = new ServerFont(*style, size);
return true; return true;
} }
+1 -4
View File
@@ -34,16 +34,13 @@ DrawData::DrawData()
fAlphaFncMode(B_ALPHA_OVERLAY), fAlphaFncMode(B_ALPHA_OVERLAY),
fPenLocation(0.0, 0.0), fPenLocation(0.0, 0.0),
fPenSize(1.0), fPenSize(1.0),
fFont(), fFont(*gFontManager->GetSystemPlain()),
fFontAliasing(false), fFontAliasing(false),
fSubPixelPrecise(false), fSubPixelPrecise(false),
fLineCapMode(B_BUTT_CAP), fLineCapMode(B_BUTT_CAP),
fLineJoinMode(B_BEVEL_JOIN), fLineJoinMode(B_BEVEL_JOIN),
fMiterLimit(B_DEFAULT_MITER_LIMIT) fMiterLimit(B_DEFAULT_MITER_LIMIT)
{ {
if (gFontManager && gFontManager->GetSystemPlain())
fFont = *(gFontManager->GetSystemPlain());
fUnscaledFontSize = fFont.Size(); fUnscaledFontSize = fFont.Size();
} }
+4 -1
View File
@@ -1601,8 +1601,11 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
FontStyle *fontStyle = gFontManager->GetStyle(familyID, styleID); FontStyle *fontStyle = gFontManager->GetStyle(familyID, styleID);
if (fontStyle != NULL) { if (fontStyle != NULL) {
font_height height;
fontStyle->GetHeight(size, height);
fLink.StartMessage(B_OK); fLink.StartMessage(B_OK);
fLink.Attach<font_height>(fontStyle->GetHeight(size)); fLink.Attach<font_height>(height);
} else } else
fLink.StartMessage(B_BAD_VALUE); fLink.StartMessage(B_BAD_VALUE);
+59 -80
View File
@@ -105,7 +105,7 @@ class FaceGetter {
FT_Face Face() FT_Face Face()
{ {
return fStyle->GetFTFace(); return fStyle->FreeTypeFace();
} }
private: private:
@@ -125,10 +125,10 @@ class FaceGetter {
\param flags Style flags as defined in <Font.h> \param flags Style flags as defined in <Font.h>
\param spacing String spacing flag as defined in <Font.h> \param spacing String spacing flag as defined in <Font.h>
*/ */
ServerFont::ServerFont(FontStyle *style, float size, ServerFont::ServerFont(FontStyle& style, float size,
float rotation, float shear, float rotation, float shear,
uint16 flags, uint8 spacing) uint16 flags, uint8 spacing)
: fStyle(style), : fStyle(&style),
fSize(size), fSize(size),
fRotation(rotation), fRotation(rotation),
fShear(shear), fShear(shear),
@@ -138,59 +138,40 @@ ServerFont::ServerFont(FontStyle *style, float size,
fDirection(B_FONT_LEFT_TO_RIGHT), fDirection(B_FONT_LEFT_TO_RIGHT),
fFace(B_REGULAR_FACE), fFace(B_REGULAR_FACE),
fEncoding(B_UNICODE_UTF8) fEncoding(B_UNICODE_UTF8)
{ {
if (fStyle) fStyle->Acquire();
fStyle->AddDependent();
} }
// TODO: fStyle should not be NULL. There should be another FontStyle
// constructor, that initializes without actually interfacing with
// freetype, so that a ServerFont can be guaranteed to be "valid".
ServerFont::ServerFont() ServerFont::ServerFont()
: fStyle(NULL), :
fSize(0.0), fStyle(NULL)
fRotation(0.0),
fShear(90.0),
fBounds(0, 0, 0, 0),
fFlags(0),
fSpacing(B_STRING_SPACING),
fDirection(B_FONT_LEFT_TO_RIGHT),
fFace(B_REGULAR_FACE),
fEncoding(B_UNICODE_UTF8)
{ {
*this = *gFontManager->GetSystemPlain();
} }
/*! /*!
\brief Copy Constructor \brief Copy Constructor
\param font ServerFont to copy \param font ServerFont to copy
*/ */
ServerFont::ServerFont(const ServerFont &font) ServerFont::ServerFont(const ServerFont &font)
: fStyle(font.fStyle), :
fSize(font.fSize), fStyle(NULL)
fRotation(font.fRotation),
fShear(font.fShear),
fBounds(0, 0, 0, 0),
fFlags(font.fFlags),
fSpacing(font.fSpacing),
fDirection(font.fDirection),
fFace(font.fFace),
fEncoding(font.fEncoding)
{ {
if (fStyle) *this = font;
fStyle->AddDependent();
} }
/*! /*!
\brief Removes itself as a dependency of its owning style. \brief Removes itself as a dependency of its owning style.
*/ */
ServerFont::~ServerFont() ServerFont::~ServerFont()
{ {
if (fStyle) fStyle->Release();
fStyle->RemoveDependent();
} }
/*! /*!
\brief Returns a copy of the specified font \brief Returns a copy of the specified font
\param The font to copy from. \param The font to copy from.
@@ -214,6 +195,7 @@ ServerFont::operator=(const ServerFont& font)
return *this; return *this;
} }
/*! /*!
\brief Returns the number of strikes in the font \brief Returns the number of strikes in the font
\return The number of strikes in the font \return The number of strikes in the font
@@ -221,41 +203,35 @@ ServerFont::operator=(const ServerFont& font)
int32 int32
ServerFont::CountTuned() ServerFont::CountTuned()
{ {
if (fStyle) return fStyle->TunedCount();
return fStyle->TunedCount();
return 0;
} }
/*! /*!
\brief Returns the file format of the font. Currently unimplemented. \brief Returns the file format of the font.
\return B_TRUETYPE_WINDOWS \return Mostly B_TRUETYPE_WINDOWS :)
*/ */
font_file_format font_file_format
ServerFont::FileFormat() ServerFont::FileFormat()
{ {
// TODO: implement ServerFont::FileFormat return fStyle->FileFormat();
return B_TRUETYPE_WINDOWS;
} }
const char* const char*
ServerFont::GetStyle() const ServerFont::GetStyle() const
{ {
if (fStyle) return fStyle->Name();
return fStyle->Name();
return NULL;
} }
const char* const char*
ServerFont::GetFamily() const ServerFont::GetFamily() const
{ {
if (fStyle) return fStyle->Family()->Name();
return fStyle->Family()->Name();
return NULL;
} }
/*! /*!
\brief Sets the ServerFont instance to whatever font is specified \brief Sets the ServerFont instance to whatever font is specified
\param familyID ID number of the family to set \param familyID ID number of the family to set
@@ -269,6 +245,9 @@ ServerFont::SetFamilyAndStyle(uint16 familyID, uint16 styleID)
if (gFontManager->Lock()) { if (gFontManager->Lock()) {
style = gFontManager->GetStyle(familyID, styleID); style = gFontManager->GetStyle(familyID, styleID);
if (style != NULL)
style->Acquire();
gFontManager->Unlock(); gFontManager->Unlock();
} }
@@ -276,10 +255,12 @@ ServerFont::SetFamilyAndStyle(uint16 familyID, uint16 styleID)
return B_ERROR; return B_ERROR;
_SetStyle(style); _SetStyle(style);
style->Release();
return B_OK; return B_OK;
} }
/*! /*!
\brief Sets the ServerFont instance to whatever font is specified \brief Sets the ServerFont instance to whatever font is specified
\param fontID the combination of family and style ID numbers \param fontID the combination of family and style ID numbers
@@ -294,6 +275,7 @@ ServerFont::SetFamilyAndStyle(uint32 fontID)
return SetFamilyAndStyle(family, style); return SetFamilyAndStyle(family, style);
} }
/*! /*!
\brief Gets the ID values for the ServerFont instance in one shot \brief Gets the ID values for the ServerFont instance in one shot
\return the combination of family and style ID numbers \return the combination of family and style ID numbers
@@ -365,7 +347,7 @@ ServerFont::GetGlyphShapes(const char charArray[], int32 numChars) const
void void
ServerFont::GetHasGlyphs(const char charArray[], int32 numChars, bool hasArray[]) const ServerFont::GetHasGlyphs(const char charArray[], int32 numChars, bool hasArray[]) const
{ {
if (!fStyle || !charArray || numChars <= 0 || !hasArray) if (!charArray || numChars <= 0 || !hasArray)
return; return;
FaceGetter getter(fStyle); FaceGetter getter(fStyle);
@@ -403,11 +385,10 @@ ServerFont::GetHasGlyphs(const char charArray[], int32 numChars, bool hasArray[]
} }
// GetEdges
void void
ServerFont::GetEdges(const char charArray[], int32 numChars, edge_info edgeArray[]) const ServerFont::GetEdges(const char charArray[], int32 numChars, edge_info edgeArray[]) const
{ {
if (!fStyle || !charArray || numChars <= 0 || !edgeArray) if (!charArray || numChars <= 0 || !edgeArray)
return; return;
FaceGetter getter(fStyle); FaceGetter getter(fStyle);
@@ -450,44 +431,43 @@ ServerFont::GetEdges(const char charArray[], int32 numChars, edge_info edgeArray
} }
// GetEscapements
BPoint* BPoint*
ServerFont::GetEscapements(const char charArray[], int32 numChars, ServerFont::GetEscapements(const char charArray[], int32 numChars,
BPoint offsetArray[]) const BPoint offsetArray[]) const
{ {
if (!fStyle || !charArray || numChars <= 0 || !offsetArray) if (!charArray || numChars <= 0 || !offsetArray)
return NULL; return NULL;
FaceGetter getter(fStyle); FaceGetter getter(fStyle);
FT_Face face = getter.Face(); FT_Face face = getter.Face();
if (!face) if (!face)
return NULL; return NULL;
FT_Set_Char_Size(face, 0, int32(fSize * 64), 72, 72); FT_Set_Char_Size(face, 0, int32(fSize * 64), 72, 72);
Angle rotation(fRotation); Angle rotation(fRotation);
Angle shear(fShear); Angle shear(fShear);
// First, rotate // First, rotate
FT_Matrix rmatrix; FT_Matrix rmatrix;
rmatrix.xx = (FT_Fixed)( rotation.Cosine()*0x10000); rmatrix.xx = (FT_Fixed)( rotation.Cosine()*0x10000);
rmatrix.xy = (FT_Fixed)(-rotation.Sine()*0x10000); rmatrix.xy = (FT_Fixed)(-rotation.Sine()*0x10000);
rmatrix.yx = (FT_Fixed)( rotation.Sine()*0x10000); rmatrix.yx = (FT_Fixed)( rotation.Sine()*0x10000);
rmatrix.yy = (FT_Fixed)( rotation.Cosine()*0x10000); rmatrix.yy = (FT_Fixed)( rotation.Cosine()*0x10000);
// Next, shear // Next, shear
FT_Matrix smatrix; FT_Matrix smatrix;
smatrix.xx = (FT_Fixed)(0x10000); smatrix.xx = (FT_Fixed)(0x10000);
smatrix.xy = (FT_Fixed)(-shear.Cosine()*0x10000); smatrix.xy = (FT_Fixed)(-shear.Cosine()*0x10000);
smatrix.yx = (FT_Fixed)(0); smatrix.yx = (FT_Fixed)(0);
smatrix.yy = (FT_Fixed)(0x10000); smatrix.yy = (FT_Fixed)(0x10000);
// Multiply togheter // Multiply togheter
FT_Matrix_Multiply(&rmatrix, &smatrix); FT_Matrix_Multiply(&rmatrix, &smatrix);
//FT_Vector pen; //FT_Vector pen;
//FT_Set_Transform(face, &smatrix, &pen); //FT_Set_Transform(face, &smatrix, &pen);
// TODO: I'm not sure if this the correct interpretation // TODO: I'm not sure if this the correct interpretation
// of the BeBook. Have actual tests been done here? // of the BeBook. Have actual tests been done here?
@@ -502,19 +482,18 @@ ServerFont::GetEscapements(const char charArray[], int32 numChars,
escapements[i].y = float(face->glyph->metrics.vertAdvance / 64) / fSize; escapements[i].y = float(face->glyph->metrics.vertAdvance / 64) / fSize;
escapements[i] += offsetArray[i]; escapements[i] += offsetArray[i];
} }
return escapements; return escapements;
} }
// GetEscapements
bool bool
ServerFont::GetEscapements(const char charArray[], int32 numChars, int32 numBytes, ServerFont::GetEscapements(const char charArray[], int32 numChars, int32 numBytes,
float widthArray[], escapement_delta delta) const float widthArray[], escapement_delta delta) const
{ {
if (!fStyle || !charArray || numChars <= 0) if (!charArray || numChars <= 0)
return false; return false;
FaceGetter getter(fStyle); FaceGetter getter(fStyle);
FT_Face face = getter.Face(); FT_Face face = getter.Face();
if (!face) if (!face)
@@ -560,7 +539,7 @@ ServerFont::GetBoundingBoxesAsString(const char charArray[], int32 numChars,
BRect rectArray[], bool string_escapement, font_metric_mode mode, BRect rectArray[], bool string_escapement, font_metric_mode mode,
escapement_delta delta) escapement_delta delta)
{ {
if (!fStyle || !charArray || numChars <= 0 || !rectArray) if (!charArray || numChars <= 0 || !rectArray)
return false; return false;
FaceGetter getter(fStyle); FaceGetter getter(fStyle);
@@ -620,7 +599,7 @@ bool
ServerFont::GetBoundingBoxesForStrings(char *charArray[], int32 lengthArray[], ServerFont::GetBoundingBoxesForStrings(char *charArray[], int32 lengthArray[],
int32 numStrings, BRect rectArray[], font_metric_mode mode, escapement_delta deltaArray[]) int32 numStrings, BRect rectArray[], font_metric_mode mode, escapement_delta deltaArray[])
{ {
if (!fStyle || !charArray || !lengthArray|| numStrings <= 0 || !rectArray || !deltaArray) if (!charArray || !lengthArray|| numStrings <= 0 || !rectArray || !deltaArray)
return false; return false;
FaceGetter getter(fStyle); FaceGetter getter(fStyle);
@@ -632,18 +611,16 @@ ServerFont::GetBoundingBoxesForStrings(char *charArray[], int32 lengthArray[],
for (int32 i = 0; i < numStrings; i++) { for (int32 i = 0; i < numStrings; i++) {
// TODO: ... // TODO: ...
} }
return true; return true;
} }
// StringWidth
float float
ServerFont::StringWidth(const char* string, int32 numBytes) const ServerFont::StringWidth(const char* string, int32 numBytes) const
{ {
if (!fStyle || !string || numBytes <= 0) if (!string || numBytes <= 0)
return 0.0; return 0.0;
FaceGetter getter(fStyle); FaceGetter getter(fStyle);
@@ -680,6 +657,7 @@ ServerFont::StringWidth(const char* string, int32 numBytes) const
return width; return width;
} }
/*! /*!
\brief Returns a BRect which encloses the entire font \brief Returns a BRect which encloses the entire font
\return A BRect which encloses the entire font \return A BRect which encloses the entire font
@@ -691,18 +669,18 @@ ServerFont::BoundingBox()
return fBounds; return fBounds;
} }
/*! /*!
\brief Obtains the height values for characters in the font in its current state \brief Obtains the height values for characters in the font in its current state
\param fh pointer to a font_height object to receive the values for the font \param fh pointer to a font_height object to receive the values for the font
*/ */
void void
ServerFont::Height(font_height *fh) const ServerFont::GetHeight(font_height& height) const
{ {
if (fh && fStyle) fStyle->GetHeight(fSize, height);
*fh = fStyle->GetHeight(fSize);
} }
// TruncateString
void void
ServerFont::TruncateString(BString* inOut, uint32 mode, float width) const ServerFont::TruncateString(BString* inOut, uint32 mode, float width) const
{ {
@@ -730,19 +708,20 @@ ServerFont::TruncateString(BString* inOut, uint32 mode, float width) const
} }
} }
// _SetStyle
void void
ServerFont::_SetStyle(FontStyle* style) ServerFont::_SetStyle(FontStyle* style)
{ {
if (style == NULL)
debugger("set NULL style!");
if (style != fStyle) { if (style != fStyle) {
// detach from old style // detach from old style
if (fStyle) if (fStyle)
fStyle->RemoveDependent(); fStyle->Release();
fStyle = style;
// attach to new style // attach to new style
if (fStyle) fStyle = style;
fStyle->AddDependent(); fStyle->Acquire();
} }
} }
@@ -1084,11 +1084,6 @@ Painter::_Clipped(const BRect& rect) const
void void
Painter::_UpdateFont() Painter::_UpdateFont()
{ {
// TODO: temporary work arround until ServerFont
// is guaranteed to be valid.
if (fFont.InitCheck() < B_OK)
return;
fTextRenderer->SetFont(fFont); fTextRenderer->SetFont(fFont);
} }