2 * Copyright 2001-2008, Haiku.
3 * Distributed under the terms of the MIT License.
6 * DarkWyrm <bpmagic@columbus.rr.com>
7 * Axel Dörfler, axeld@pinc-software.de
10 /** Classes to represent font styles and families */
13 #include "FontFamily.h"
14 #include "ServerFont.h"
15 #include "FontManager.h"
17 #include <FontPrivate.h>
22 static BLocker
sFontLock("font lock");
27 \param filepath path to a font file
28 \param face FreeType handle for the font file after it is loaded - it will
29 be kept open until the FontStyle is destroyed
31 FontStyle::FontStyle(node_ref
& nodeRef
, const char* path
, FT_Face face
)
34 fName(face
->style_name
),
40 fFace(_TranslateStyleToFace(face
->style_name
))
42 fName
.Truncate(B_FONT_STYLE_LENGTH
);
43 // make sure this style can be found using the Be API
45 fHeight
.ascent
= (double)face
->ascender
/ face
->units_per_EM
;
46 fHeight
.descent
= (double)-face
->descender
/ face
->units_per_EM
;
47 // FT2's descent numbers are negative. Be's is positive
49 // FT2 doesn't provide a linegap, but according to the docs, we can
50 // calculate it because height = ascending + descending + leading
51 fHeight
.leading
= (double)(face
->height
- face
->ascender
+ face
->descender
)
56 FontStyle::~FontStyle()
58 // make sure the font server is ours
59 if (fFamily
!= NULL
&& gFontManager
->Lock()) {
60 gFontManager
->RemoveStyle(this);
61 gFontManager
->Unlock();
64 FT_Done_Face(fFreeTypeFace
);
69 FontStyle::Hash() const
71 return (ID() << 16) | fFamily
->ID();
76 FontStyle::CompareTo(Hashable
& other
) const
78 // our hash values are unique (unless you have more than 65536 font
79 // families installed...)
80 return Hash() == other
.Hash();
87 return sFontLock
.Lock();
99 FontStyle::GetHeight(float size
, font_height
& height
) const
101 height
.ascent
= fHeight
.ascent
* size
;
102 height
.descent
= fHeight
.descent
* size
;
103 height
.leading
= fHeight
.leading
* size
;
108 \brief Returns the path to the style's font file
109 \return The style's font file path
112 FontStyle::Path() const
119 \brief Updates the path of the font style in case the style
120 has been moved around.
123 FontStyle::UpdatePath(const node_ref
& parentNodeRef
)
126 ref
.device
= parentNodeRef
.device
;
127 ref
.directory
= parentNodeRef
.node
;
128 ref
.set_name(fPath
.Leaf());
135 \brief Unlike BFont::Flags() this returns the extra flags field as used
136 in the private part of BFont.
139 FontStyle::Flags() const
141 uint32 flags
= uint32(Direction()) << B_PRIVATE_FONT_DIRECTION_SHIFT
;
145 if (IsFullAndHalfFixed())
146 flags
|= B_PRIVATE_FONT_IS_FULL_AND_HALF_FIXED
;
147 if (TunedCount() > 0)
148 flags
|= B_HAS_TUNED_FONT
;
150 flags
|= B_PRIVATE_FONT_HAS_KERNING
;
157 \brief Updates the given face to match the one from this style
159 The specified font face often doesn't match the exact face of
160 a style. This method will preserve the attributes of the face
161 that this style does not alter, and will only update the
162 attributes that matter to this style.
163 The font renderer could then emulate the other face attributes
164 taking this style as a base.
167 FontStyle::PreservedFace(uint16 face
) const
169 // TODO: make this better
170 face
&= ~(B_REGULAR_FACE
| B_BOLD_FACE
| B_ITALIC_FACE
);
178 FontStyle::UpdateFace(FT_Face face
)
180 if (!sFontLock
.IsLocked()) {
181 debugger("UpdateFace() called without having locked FontStyle!");
185 // we only accept the face if it hasn't change its style
187 BString name
= face
->style_name
;
188 name
.Truncate(B_FONT_STYLE_LENGTH
);
193 FT_Done_Face(fFreeTypeFace
);
194 fFreeTypeFace
= face
;
200 FontStyle::_SetFontFamily(FontFamily
* family
, uint16 id
)
208 FontStyle::_TranslateStyleToFace(const char* name
) const
213 BString
string(name
);
216 if (string
.IFindFirst("bold") >= 0)
219 if (string
.IFindFirst("italic") >= 0
220 || string
.IFindFirst("oblique") >= 0)
221 face
|= B_ITALIC_FACE
;
223 if (string
.IFindFirst("condensed") >= 0)
224 face
|= B_CONDENSED_FACE
;
226 if (string
.IFindFirst("light") >= 0)
227 face
|= B_LIGHT_FACE
;
229 if (string
.IFindFirst("heavy") >= 0
230 || string
.IFindFirst("black") >= 0)
231 face
|= B_HEAVY_FACE
;
234 return B_REGULAR_FACE
;