vfs: check userland buffers before reading them.
[haiku.git] / src / servers / app / font / FontFamily.cpp
blob3d1532e60a6b014f7c30dc8f8a91dc2e1a473883
1 /*
2 * Copyright 2001-2008, Haiku.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * DarkWyrm <bpmagic@columbus.rr.com>
7 * Axel Dörfler, axeld@pinc-software.de
8 */
10 /** Classes to represent font styles and families */
13 #include "FontFamily.h"
15 #include "FontManager.h"
17 #include <FontPrivate.h>
20 const uint32 kInvalidFamilyFlags = ~(uint32)0;
23 static int
24 font_score(const FontStyle* style)
26 int score = 0;
27 if (style->Face() & B_REGULAR_FACE)
28 score += 10;
29 else {
30 if (style->Face() & B_BOLD_FACE)
31 score += 5;
32 if (style->Face() & B_ITALIC_FACE)
33 score--;
36 return score;
40 static int
41 compare_font_styles(const FontStyle* a, const FontStyle* b)
43 // Regular fonts come first, then bold, then italics
44 return font_score(b) - font_score(a);
48 // #pragma mark -
51 /*!
52 \brief Constructor
53 \param namestr Name of the family
55 FontFamily::FontFamily(const char *name, uint16 id)
57 fName(name),
58 fID(id),
59 fNextID(0),
60 fFlags(kInvalidFamilyFlags)
62 fName.Truncate(B_FONT_FAMILY_LENGTH);
63 // make sure this family can be found using the Be API
67 /*!
68 \brief Destructor
70 Deletes all attached styles. Note that a FontFamily must only be deleted
71 by the font manager.
73 FontFamily::~FontFamily()
75 for (int32 i = fStyles.CountItems(); i-- > 0;) {
76 FontStyle* style = fStyles.RemoveItemAt(i);
78 // we remove us before deleting the style, so that the font manager
79 // is not contacted to remove the style from us
80 style->_SetFontFamily(NULL, -1);
81 delete style;
86 /*!
87 \brief Returns the name of the family
88 \return The family's name
90 const char*
91 FontFamily::Name() const
93 return fName.String();
97 /*!
98 \brief Adds the style to the family
99 \param style pointer to FontStyle object to be added
101 bool
102 FontFamily::AddStyle(FontStyle *style)
104 if (!style)
105 return false;
107 // Don't add if it already is in the family.
108 int32 count = fStyles.CountItems();
109 for (int32 i = 0; i < count; i++) {
110 FontStyle *item = fStyles.ItemAt(i);
111 if (!strcmp(item->Name(), style->Name()))
112 return false;
115 if (!fStyles.BinaryInsert(style, compare_font_styles))
116 return false;
118 style->_SetFontFamily(this, fNextID++);
120 // force a refresh if a request for font flags is needed
121 fFlags = kInvalidFamilyFlags;
123 return true;
128 \brief Removes a style from the family.
130 The font style will not be deleted.
132 bool
133 FontFamily::RemoveStyle(FontStyle* style)
135 if (!gFontManager->IsLocked()) {
136 debugger("FontFamily::RemoveStyle() called without having the font manager locked!");
137 return false;
140 if (!fStyles.RemoveItem(style))
141 return false;
143 style->_SetFontFamily(NULL, -1);
145 // force a refresh if a request for font flags is needed
146 fFlags = kInvalidFamilyFlags;
147 return true;
152 \brief Returns the number of styles in the family
153 \return The number of styles in the family
155 int32
156 FontFamily::CountStyles() const
158 return fStyles.CountItems();
162 FontStyle*
163 FontFamily::_FindStyle(const char* name) const
165 int32 count = fStyles.CountItems();
166 if (!name || count < 1)
167 return NULL;
169 for (int32 i = 0; i < count; i++) {
170 FontStyle *style = fStyles.ItemAt(i);
171 if (!strcmp(style->Name(), name))
172 return style;
175 return NULL;
180 \brief Determines whether the style belongs to the family
181 \param style Name of the style being checked
182 \return True if it belongs, false if not
184 bool
185 FontFamily::HasStyle(const char *styleName) const
187 return _FindStyle(styleName) != NULL;
192 \brief Returns the name of a style in the family
193 \param index list index of the style to be found
194 \return name of the style or NULL if the index is not valid
196 FontStyle*
197 FontFamily::StyleAt(int32 index) const
199 return fStyles.ItemAt(index);
204 \brief Get the FontStyle object for the name given
205 \param style Name of the style to be obtained
206 \return The FontStyle object or NULL if none was found.
208 The object returned belongs to the family and must not be deleted.
210 FontStyle*
211 FontFamily::GetStyle(const char *name) const
213 if (name == NULL || !name[0])
214 return NULL;
216 FontStyle* style = _FindStyle(name);
217 if (style != NULL)
218 return style;
220 // try alternative names
222 if (!strcmp(name, "Roman") || !strcmp(name, "Regular")
223 || !strcmp(name, "Book")) {
224 style = _FindStyle("Roman");
225 if (style == NULL) {
226 style = _FindStyle("Regular");
227 if (style == NULL)
228 style = _FindStyle("Book");
230 return style;
233 BString alternative = name;
234 if (alternative.FindFirst("Italic") >= 0) {
235 alternative.ReplaceFirst("Italic", "Oblique");
236 return _FindStyle(alternative.String());
238 if (alternative.FindFirst("Oblique") >= 0) {
239 alternative.ReplaceFirst("Oblique", "Italic");
240 return _FindStyle(alternative.String());
243 return NULL;
247 FontStyle*
248 FontFamily::GetStyleByID(uint16 id) const
250 int32 count = fStyles.CountItems();
251 for (int32 i = 0; i < count; i++) {
252 FontStyle* style = fStyles.ItemAt(i);
253 if (style->ID() == id)
254 return style;
257 return NULL;
261 FontStyle*
262 FontFamily::GetStyleMatchingFace(uint16 face) const
264 // TODO: support other faces (strike through, underlined, outlines...)
265 face &= B_BOLD_FACE | B_ITALIC_FACE | B_REGULAR_FACE | B_CONDENSED_FACE
266 | B_LIGHT_FACE | B_HEAVY_FACE;
268 int32 count = fStyles.CountItems();
269 for (int32 i = 0; i < count; i++) {
270 FontStyle* style = fStyles.ItemAt(i);
272 if (style->Face() == face)
273 return style;
276 return NULL;
280 uint32
281 FontFamily::Flags()
283 if (fFlags == kInvalidFamilyFlags) {
284 fFlags = 0;
286 int32 count = fStyles.CountItems();
287 for (int32 i = 0; i < count; i++) {
288 FontStyle* style = fStyles.ItemAt(i);
290 if (style->IsFixedWidth())
291 fFlags |= B_IS_FIXED;
292 if (style->IsFullAndHalfFixed())
293 fFlags |= B_PRIVATE_FONT_IS_FULL_AND_HALF_FIXED;
294 if (style->TunedCount() > 0)
295 fFlags |= B_HAS_TUNED_FONT;
299 return fFlags;