diff --git a/headers/os/interface/Font.h b/headers/os/interface/Font.h index 6ebe42f1d2..32a2309f74 100644 --- a/headers/os/interface/Font.h +++ b/headers/os/interface/Font.h @@ -74,7 +74,11 @@ enum { B_OUTLINED_FACE = 0x0008, B_STRIKEOUT_FACE = 0x0010, B_BOLD_FACE = 0x0020, - B_REGULAR_FACE = 0x0040 + B_REGULAR_FACE = 0x0040, + // new in Haiku: + B_CONDENSED_FACE = 0x0080, + B_LIGHT_FACE = 0x0100, + B_HEAVY_FACE = 0x0200, }; enum font_metric_mode { diff --git a/src/servers/app/FontFamily.cpp b/src/servers/app/FontFamily.cpp index 3b6aa4c53c..58b58218a3 100644 --- a/src/servers/app/FontFamily.cpp +++ b/src/servers/app/FontFamily.cpp @@ -259,8 +259,9 @@ FontFamily::GetStyleByID(uint16 id) const FontStyle* FontFamily::GetStyleMatchingFace(uint16 face) const { - // we currently only use bold/italic/regular faces - face &= B_BOLD_FACE | B_ITALIC_FACE | B_REGULAR_FACE; + // TODO: support other faces (strike through, underlined, outlines...) + face &= B_BOLD_FACE | B_ITALIC_FACE | B_REGULAR_FACE | B_CONDENSED_FACE + | B_LIGHT_FACE | B_HEAVY_FACE; int32 count = fStyles.CountItems(); for (int32 i = 0; i < count; i++) { diff --git a/src/servers/app/FontManager.cpp b/src/servers/app/FontManager.cpp index 92053e8cff..464a7bb52c 100644 --- a/src/servers/app/FontManager.cpp +++ b/src/servers/app/FontManager.cpp @@ -862,6 +862,23 @@ FontManager::CountStyles(const char *familyName) } +/*! \brief Counts the number of styles available in a font family + \param family Name of the font family to scan + \return The number of font styles currently available for the font family +*/ +int32 +FontManager::CountStyles(uint16 familyID) +{ + _ScanFontsIfNecessary(); + + FontFamily *family = GetFamily(familyID); + if (family) + return family->CountStyles(); + + return 0; +} + + FontFamily* FontManager::FamilyAt(int32 index) const { @@ -935,6 +952,17 @@ FontManager::GetStyleByIndex(const char* familyName, int32 index) } +FontStyle* +FontManager::GetStyleByIndex(uint16 familyID, int32 index) +{ + FontFamily* family = GetFamily(familyID); + if (family != NULL) + return family->StyleAt(index); + + return NULL; +} + + /*! \brief Retrieves the FontStyle object that comes closest to the one specified. diff --git a/src/servers/app/FontManager.h b/src/servers/app/FontManager.h index 22dad4d3b0..9d2010edb7 100644 --- a/src/servers/app/FontManager.h +++ b/src/servers/app/FontManager.h @@ -45,12 +45,14 @@ class FontManager : public BLooper { int32 CountFamilies(); int32 CountStyles(const char *family); + int32 CountStyles(uint16 familyID); FontFamily* FamilyAt(int32 index) const; FontFamily *GetFamily(uint16 familyID) const; FontFamily *GetFamily(const char *name); FontStyle *GetStyleByIndex(const char *family, int32 index); + FontStyle *GetStyleByIndex(uint16 familyID, int32 index); FontStyle *GetStyle(const char *family, const char *style, uint16 familyID = 0xffff, uint16 styleID = 0xffff, uint16 face = 0); FontStyle *GetStyle(const char *family, uint16 styleID); diff --git a/src/servers/app/FontStyle.cpp b/src/servers/app/FontStyle.cpp index 4421381326..84042b96e3 100644 --- a/src/servers/app/FontStyle.cpp +++ b/src/servers/app/FontStyle.cpp @@ -222,7 +222,7 @@ FontStyle::_SetFontFamily(FontFamily* family, uint16 id) uint16 -FontStyle::_TranslateStyleToFace(const char *name) const +FontStyle::_TranslateStyleToFace(const char* name) const { if (name == NULL) return 0; @@ -237,6 +237,16 @@ FontStyle::_TranslateStyleToFace(const char *name) const || string.IFindFirst("oblique") >= 0) face |= B_ITALIC_FACE; + if (string.IFindFirst("condensed") >= 0) + face |= B_CONDENSED_FACE; + + if (string.IFindFirst("light") >= 0) + face |= B_LIGHT_FACE; + + if (string.IFindFirst("heavy") >= 0 + || string.IFindFirst("black") >= 0) + face |= B_HEAVY_FACE; + if (face == 0) return B_REGULAR_FACE; diff --git a/src/servers/app/ServerFont.cpp b/src/servers/app/ServerFont.cpp index e0510f7be4..053d539057 100644 --- a/src/servers/app/ServerFont.cpp +++ b/src/servers/app/ServerFont.cpp @@ -292,11 +292,40 @@ ServerFont::SetFamilyAndStyle(uint32 fontID) } -void -ServerFont::SetFace(uint32 face) +status_t +ServerFont::SetFace(uint16 face) { - // TODO: change font style as requested! - fFace = face; + // TODO: This needs further investigation. The face variable is actually + // flags, but some of them are not enforcable at the same time. Also don't + // confuse the Be API "face" with the Freetype face, which is just an + // index in case a single font file exports multiple font faces. The + // FontStyle class takes care of mapping the font style name to the Be + // API face flags in FontStyle::_TranslateStyleToFace(). + + FontStyle* style = NULL; + uint16 familyID = FamilyID(); + if (gFontManager->Lock()) { + int32 count = gFontManager->CountStyles(familyID); + for (int32 i = 0; i < count; i++) { + style = gFontManager->GetStyleByIndex(familyID, i); + if (style == NULL) + break; + if (style->Face() == face) { + style->Acquire(); + break; + } + } + + gFontManager->Unlock(); + } + + if (!style) + return B_ERROR; + + SetStyle(style); + style->Release(); + + return B_OK; } diff --git a/src/servers/app/ServerFont.h b/src/servers/app/ServerFont.h index ae028c862c..a5297f6f8a 100644 --- a/src/servers/app/ServerFont.h +++ b/src/servers/app/ServerFont.h @@ -93,7 +93,7 @@ class ServerFont { { fRotation = value; } void SetFalseBoldWidth(float value) { fFalseBoldWidth = value; } - void SetFace(uint32 face); + status_t SetFace(uint16 face); bool IsFixedWidth() const { return fStyle->IsFixedWidth(); }