More font work:

* simplified BFont::SetFamily*() server communication - there is now only
  AS_SET_FAMILY_AND_STYLE left, but at least that one works correctly.
* BFont::fFace is now always updated correctly.
* Moved the fFace masking to the server - BFont doesn't know enough to do
  this correctly, anyway.
* Only one version of get_font_style() worked correctly.
* Font family/style ID and index were used completely mixed up - this
  would have become an issue as soon as the font list changes during
  runtime.
* Enabled AS_GET_FONT_DIRECTION again - missing functionality should only
  be taken into account on lowest level as long as it can be emulated.
* Made FontServer a bit clearer to use (more to come).
* fixed several allocation leaks in the font server communication.
* New FontStyle::Direction() method, that currently only returns
  B_FONT_LEFT_TO_RIGHT, though.
* more cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14618 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2005-11-01 16:28:01 +00:00
parent 42f8a2603e
commit b8cde4497e
7 changed files with 475 additions and 507 deletions
+2 -5
View File
@@ -3,8 +3,8 @@
* 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 _APPSERVER_PROTOCOL_ #ifndef _APPSERVER_PROTOCOL_
@@ -125,10 +125,7 @@ enum {
AS_GET_FONT_HEIGHT, AS_GET_FONT_HEIGHT,
AS_QUERY_FONT_FIXED, AS_QUERY_FONT_FIXED,
AS_SET_FAMILY_NAME,
AS_SET_FAMILY_AND_STYLE, AS_SET_FAMILY_AND_STYLE,
AS_SET_FAMILY_AND_STYLE_FROM_ID,
AS_SET_FAMILY_AND_FACE,
AS_COUNT_FONT_FAMILIES, AS_COUNT_FONT_FAMILIES,
AS_COUNT_FONT_STYLES, AS_COUNT_FONT_STYLES,
+6 -3
View File
@@ -147,10 +147,13 @@ class FontStyle : public SharedObject, public BLocker {
inline uint16 Face() const inline uint16 Face() const
{ return fFace; } { return fFace; }
uint16 PreservedFace(uint16) const;
const char* Path() const; const char* Path() const;
font_height GetHeight(const float& size) const; font_height GetHeight(const float& size) const;
font_direction Direction() const
{ return B_FONT_LEFT_TO_RIGHT; }
inline FT_Face GetFTFace() const inline FT_Face GetFTFace() const
{ return fFTFace; } { return fFTFace; }
@@ -206,8 +209,8 @@ class FontFamily : public SharedObject {
void RemoveStyle(FontStyle* style); void RemoveStyle(FontStyle* style);
FontStyle* GetStyle(const char* style) const; FontStyle* GetStyle(const char* style) const;
FontStyle* GetStyleWithFace(uint16 face) const; FontStyle* GetStyleMatchingFace(uint16 face) const;
FontStyle* GetStyleWithID(uint16 face) const; FontStyle* GetStyleByID(uint16 face) const;
uint16 ID() const uint16 ID() const
{ return fID; } { return fID; }
+47 -46
View File
@@ -4,15 +4,17 @@
* *
* Authors: * Authors:
* DarkWyrm <[email protected]> * DarkWyrm <[email protected]>
* Axel Dörfler, [email protected]
*/ */
#ifndef FONTSERVER_H_ #ifndef FONT_SERVER_H
#define FONTSERVER_H_ #define FONT_SERVER_H
#include <OS.h>
#include <List.h>
#include <SupportDefs.h>
#include <Font.h> #include <Font.h>
#include <Locker.h> #include <Locker.h>
#include <OS.h>
#include <ObjectList.h>
#include <SupportDefs.h>
#include <ft2build.h> #include <ft2build.h>
#include FT_FREETYPE_H #include FT_FREETYPE_H
@@ -22,60 +24,59 @@ class FontFamily;
class FontStyle; class FontStyle;
class ServerFont; class ServerFont;
/*! /*!
\class FontServer FontServer.h \class FontServer FontServer.h
\brief Manager for the largest part of the font subsystem \brief Manager for the largest part of the font subsystem
*/ */
class FontServer : public BLocker { class FontServer : public BLocker {
public: public:
FontServer(); FontServer();
~FontServer(); ~FontServer();
/*! status_t InitCheck() { return fInitStatus; }
\brief Determines whether the font server has started up properly
\return true if so, false if not.
*/
bool IsInitialized() { return fInit; }
int32 CountFamilies();
int32 CountStyles(const char *family);
void RemoveFamily(const char *family);
void ScanSystemFolders();
status_t ScanDirectory(const char *path);
void SaveList();
const char *GetFamilyName(uint16 id) const; int32 CountFamilies();
const char *GetStyleName(const char *family, uint16 id) const; int32 CountStyles(const char *family);
void RemoveFamily(const char *family);
void ScanSystemFolders();
status_t ScanDirectory(const char *path);
void SaveList();
FontStyle *GetStyle(const char *family, const char *style, uint16 face = 0); FontFamily* GetFamilyByIndex(int32 index) const;
FontStyle *GetStyle(const char *family, uint16 id) const; FontFamily *GetFamily(uint16 familyID) const;
FontStyle *GetStyle(uint16 familyID, uint16 styleID); FontFamily *GetFamily(const char *name) const;
FontFamily *GetFamily(uint16 familyID) const;
FontFamily *GetFamily(const char *name) const;
ServerFont *GetSystemPlain(); FontStyle *GetStyleByIndex(const char *family, int32 index) const;
ServerFont *GetSystemBold(); FontStyle *GetStyle(const char *family, const char *style, uint16 familyID = 0xffff,
ServerFont *GetSystemFixed(); uint16 styleID = 0xffff, uint16 face = 0);
FontStyle *GetStyle(const char *family, uint16 styleID);
FontStyle *GetStyle(uint16 familyID, uint16 styleID);
bool SetSystemPlain(const char *family, const char *style, float size); ServerFont *GetSystemPlain();
bool SetSystemBold(const char *family, const char *style, float size); ServerFont *GetSystemBold();
bool SetSystemFixed(const char *family, const char *style, float size); ServerFont *GetSystemFixed();
bool FontsNeedUpdated() { return fNeedUpdate; } bool SetSystemPlain(const char *family, const char *style, float size);
/*! bool SetSystemBold(const char *family, const char *style, float size);
\brief Called when the fonts list has been updated bool SetSystemFixed(const char *family, const char *style, float size);
*/
void FontsUpdated() { fNeedUpdate = false; }
protected: bool FontsNeedUpdated() { return fNeedUpdate; }
uint16 TranslateStyleToFace(const char *name) const; /*!
\brief Called when the fonts list has been updated
FT_CharMap _GetSupportedCharmap(const FT_Face &face); */
void FontsUpdated() { fNeedUpdate = false; }
private: protected:
bool fInit; uint16 TranslateStyleToFace(const char *name) const;
BList fFamilies;
ServerFont *fPlain, *fBold, *fFixed; FT_CharMap _GetSupportedCharmap(const FT_Face &face);
bool fNeedUpdate;
private:
status_t fInitStatus;
BObjectList<FontFamily> fFamilies;
ServerFont *fPlain, *fBold, *fFixed;
bool fNeedUpdate;
}; };
extern FTC_Manager ftmanager; extern FTC_Manager ftmanager;
+85 -117
View File
@@ -72,7 +72,7 @@ _font_control_(BFont *font, int32 cmd, void *data)
int32 code; int32 code;
if (link.FlushWithReply(code) != B_OK if (link.FlushWithReply(code) != B_OK
|| code != SERVER_TRUE) { || code != B_OK) {
printf("DEBUG: Couldn't initialize font in _font_control()\n"); printf("DEBUG: Couldn't initialize font in _font_control()\n");
return; return;
} }
@@ -137,7 +137,7 @@ count_font_families(void)
link.StartMessage(AS_COUNT_FONT_FAMILIES); link.StartMessage(AS_COUNT_FONT_FAMILIES);
if (link.FlushWithReply(code) != B_OK if (link.FlushWithReply(code) != B_OK
|| code != SERVER_TRUE) || code != B_OK)
return -1; return -1;
link.Read<int32>(&count); link.Read<int32>(&count);
@@ -160,7 +160,7 @@ count_font_styles(font_family name)
link.Attach(name, sizeof(font_family)); link.Attach(name, sizeof(font_family));
if (link.FlushWithReply(code) != B_OK if (link.FlushWithReply(code) != B_OK
|| code != SERVER_TRUE) || code != B_OK)
return -1; return -1;
link.Read<int32>(&count); link.Read<int32>(&count);
@@ -190,7 +190,7 @@ get_font_family(int32 index, font_family *name, uint32 *flags)
link.Attach<int32>(index); link.Attach<int32>(index);
if (link.FlushWithReply(code) != B_OK if (link.FlushWithReply(code) != B_OK
|| code != SERVER_TRUE) || code != B_OK)
return B_ERROR; return B_ERROR;
link.Read<font_family>(name); link.Read<font_family>(name);
@@ -213,35 +213,10 @@ get_font_family(int32 index, font_family *name, uint32 *flags)
*/ */
status_t status_t
get_font_style(font_family family, int32 index, font_style *name, get_font_style(font_family family, int32 index, font_style *_name,
uint32 *flags) uint32 *_flags)
{ {
if (!name) return get_font_style(family, index, _name, NULL, _flags);
return B_BAD_VALUE;
int32 code;
BPrivate::AppServerLink link;
link.StartMessage(AS_GET_STYLE_NAME);
link.Attach(family, sizeof(font_family));
link.Attach<int32>(index);
if (link.FlushWithReply(code) != B_OK
|| code != SERVER_TRUE)
return B_ERROR;
font_style style;
link.Read<font_style>(&style);
if (name)
strcpy(*name, style);
uint32 value;
link.Read<uint32>(&value); // face - unused
link.Read<uint32>(&value); // flags
if (flags)
*flags = value;
return B_OK;
} }
@@ -250,7 +225,7 @@ get_font_style(font_family family, int32 index, font_style *name,
\param index Unique font identifier code. \param index Unique font identifier code.
\param name font_family string to receive the name of the family \param name font_family string to receive the name of the family
\param face recipient of font face value, such as B_REGULAR_FACE \param face recipient of font face value, such as B_REGULAR_FACE
\param flags iF non-NULL, the values of the flags IS_FIXED and B_HAS_TUNED_FONT are returned \param flags if non-NULL, the values of the flags IS_FIXED and B_HAS_TUNED_FONT are returned
\return B_ERROR if the index does not correspond to a font style \return B_ERROR if the index does not correspond to a font style
The face value returned by this function is not very reliable. At the same time, the value The face value returned by this function is not very reliable. At the same time, the value
@@ -258,27 +233,35 @@ get_font_style(font_family family, int32 index, font_style *name,
*/ */
status_t status_t
get_font_style(font_family family, int32 index, font_style *name, get_font_style(font_family family, int32 index, font_style *_name,
uint16 *face, uint32 *flags) uint16 *_face, uint32 *_flags)
{ {
if (!name || !face) if (_name == NULL)
return B_BAD_VALUE; return B_BAD_VALUE;
int32 code; // TODO: maybe cache the whole font list locally?
BPrivate::AppServerLink link;
BPrivate::AppServerLink link;
link.StartMessage(AS_GET_STYLE_NAME); link.StartMessage(AS_GET_STYLE_NAME);
link.Attach(family, sizeof(font_family)); link.AttachString(family);
link.Attach<int32>(index); link.Attach<int32>(index);
if (link.FlushWithReply(code) != B_OK int32 status;
|| code != SERVER_TRUE) if (link.FlushWithReply(status) != B_OK
return B_ERROR; || status != B_OK)
return status;
link.Read<font_style>(name); link.ReadString(*_name, sizeof(font_style));
link.Read<uint16>(face);
if (flags) uint16 face;
link.Read<uint32>(flags); uint32 flags;
link.Read<uint16>(&face);
link.Read<uint32>(&flags);
if (_face)
*_face = face;
if (_flags)
*_flags = flags;
return B_OK; return B_OK;
} }
@@ -304,7 +287,7 @@ update_font_families(bool checkOnly)
link.Attach<bool>(checkOnly); link.Attach<bool>(checkOnly);
if (link.FlushWithReply(code) != B_OK if (link.FlushWithReply(code) != B_OK
|| code != SERVER_TRUE) || code != B_OK)
return false; return false;
link.Read<bool>(&value); link.Read<bool>(&value);
@@ -395,6 +378,8 @@ BFont::SetFamilyAndStyle(const font_family family, const font_style style)
link.StartMessage(AS_SET_FAMILY_AND_STYLE); link.StartMessage(AS_SET_FAMILY_AND_STYLE);
link.AttachString(family); link.AttachString(family);
link.AttachString(style); link.AttachString(style);
link.Attach<uint16>(fFamilyID);
link.Attach<uint16>(0xffff);
link.Attach<uint16>(fFace); link.Attach<uint16>(fFace);
int32 status; int32 status;
@@ -423,32 +408,28 @@ BFont::SetFamilyAndStyle(uint32 fontcode)
// is a problem because the face flag includes Regular/Bold/Italic information in // is a problem because the face flag includes Regular/Bold/Italic information in
// addition to stuff like underlining and strikethrough. As a result, this will // addition to stuff like underlining and strikethrough. As a result, this will
// need a trip to the server and, thus, be slower than R5's in order to be correct // need a trip to the server and, thus, be slower than R5's in order to be correct
uint16 family, style, face;
int32 code;
BPrivate::AppServerLink link;
uint16 family, style;
style = fontcode & 0xFFFF; style = fontcode & 0xFFFF;
family = (fontcode & 0xFFFF0000) >> 16; family = (fontcode & 0xFFFF0000) >> 16;
link.StartMessage(AS_SET_FAMILY_AND_STYLE_FROM_ID); BPrivate::AppServerLink link;
link.StartMessage(AS_SET_FAMILY_AND_STYLE);
link.AttachString(NULL); // no family and style name
link.AttachString(NULL);
link.Attach<uint16>(family); link.Attach<uint16>(family);
link.Attach<uint16>(style); link.Attach<uint16>(style);
link.Attach<uint16>(fFace);
int32 code;
if (link.FlushWithReply(code) != B_OK if (link.FlushWithReply(code) != B_OK
|| code != SERVER_TRUE) || code != B_OK)
return; return;
link.Read<uint16>(&face); link.Read<uint16>(&fFamilyID);
link.Read<uint16>(&fStyleID);
fStyleID = style; link.Read<uint16>(&fFace);
fFamilyID = family;
fHeight.ascent = kUninitializedAscent; fHeight.ascent = kUninitializedAscent;
// Mask off any references in the face to Bold/Normal/Italic and set the face
// value to reflect the new font style
fFace &= B_UNDERSCORE_FACE | B_NEGATIVE_FACE | B_OUTLINED_FACE | B_STRIKEOUT_FACE;
fFace |= face;
} }
@@ -466,28 +447,24 @@ BFont::SetFamilyAndStyle(uint32 fontcode)
status_t status_t
BFont::SetFamilyAndFace(const font_family family, uint16 face) BFont::SetFamilyAndFace(const font_family family, uint16 face)
{ {
if (face & (B_ITALIC_FACE | B_UNDERSCORE_FACE | B_NEGATIVE_FACE | B_OUTLINED_FACE BPrivate::AppServerLink link;
| B_STRIKEOUT_FACE | B_BOLD_FACE | B_REGULAR_FACE) != 0) link.StartMessage(AS_SET_FAMILY_AND_STYLE);
fFace = face; link.AttachString(family);
link.AttachString(NULL); // no style given
if (family) { link.Attach<uint16>(fFamilyID);
int32 code; link.Attach<uint16>(0xffff);
BPrivate::AppServerLink link; link.Attach<uint16>(face);
link.StartMessage(AS_SET_FAMILY_AND_FACE); int32 status;
link.Attach(family, sizeof(font_family)); if (link.FlushWithReply(status) != B_OK
link.Attach<uint16>(face); || status != B_OK)
return status;
if (link.FlushWithReply(code) != B_OK
|| code != SERVER_TRUE)
return B_ERROR;
link.Read<uint16>(&fFamilyID);
link.Read<uint16>(&fStyleID);
} else
fFace = face;
link.Read<uint16>(&fFamilyID);
link.Read<uint16>(&fStyleID);
link.Read<uint16>(&fFace);
fHeight.ascent = kUninitializedAscent; fHeight.ascent = kUninitializedAscent;
return B_OK; return B_OK;
} }
@@ -533,12 +510,10 @@ BFont::SetEncoding(uint8 encoding)
void void
BFont::SetFace(uint16 face) BFont::SetFace(uint16 face)
{ {
// TODO: Should the server ignore faces it doesn't have, or should if (face == fFace)
// it try to emulate faces it doesn't have, or should it correct return;
// the face value to something it has?
// TODO: don't we have to update the fStyleID? SetFamilyAndFace(NULL, face);
fFace = face;
fHeight.ascent = kUninitializedAscent;
} }
@@ -565,15 +540,14 @@ BFont::GetFamilyAndStyle(font_family *family, font_style *style) const
if (style == NULL) if (style == NULL)
style = &styleBuffer; style = &styleBuffer;
int32 code;
BPrivate::AppServerLink link; BPrivate::AppServerLink link;
link.StartMessage(AS_GET_FAMILY_AND_STYLE); link.StartMessage(AS_GET_FAMILY_AND_STYLE);
link.Attach<uint16>(fFamilyID); link.Attach<uint16>(fFamilyID);
link.Attach<uint16>(fStyleID); link.Attach<uint16>(fStyleID);
int32 code;
if (link.FlushWithReply(code) != B_OK if (link.FlushWithReply(code) != B_OK
|| code != SERVER_TRUE) { || code != B_OK) {
// the least we can do is to clear the buffers // the least we can do is to clear the buffers
memset(family, 0, sizeof(font_family)); memset(family, 0, sizeof(font_family));
memset(style, 0, sizeof(font_style)); memset(style, 0, sizeof(font_style));
@@ -644,15 +618,14 @@ BFont::Flags(void) const
font_direction font_direction
BFont::Direction(void) const BFont::Direction(void) const
{ {
int32 code;
BPrivate::AppServerLink link; BPrivate::AppServerLink link;
link.StartMessage(AS_GET_FONT_DIRECTION); link.StartMessage(AS_GET_FONT_DIRECTION);
link.Attach<uint16>(fFamilyID); link.Attach<uint16>(fFamilyID);
link.Attach<uint16>(fStyleID); link.Attach<uint16>(fStyleID);
int32 code;
if (link.FlushWithReply(code) != B_OK if (link.FlushWithReply(code) != B_OK
|| code != SERVER_TRUE) || code != B_OK)
return B_FONT_LEFT_TO_RIGHT; return B_FONT_LEFT_TO_RIGHT;
font_direction fdir; font_direction fdir;
@@ -664,15 +637,14 @@ BFont::Direction(void) const
bool bool
BFont::IsFixed(void) const BFont::IsFixed(void) const
{ {
int32 code;
BPrivate::AppServerLink link; BPrivate::AppServerLink link;
link.StartMessage(AS_QUERY_FONT_FIXED); link.StartMessage(AS_QUERY_FONT_FIXED);
link.Attach<uint16>(fFamilyID); link.Attach<uint16>(fFamilyID);
link.Attach<uint16>(fStyleID); link.Attach<uint16>(fStyleID);
int32 code;
if (link.FlushWithReply(code) != B_OK if (link.FlushWithReply(code) != B_OK
|| code != SERVER_TRUE) || code != B_OK)
return false; return false;
bool fixed; bool fixed;
@@ -698,15 +670,14 @@ BFont::IsFullAndHalfFixed(void) const
BRect BRect
BFont::BoundingBox(void) const BFont::BoundingBox(void) const
{ {
int32 code;
BPrivate::AppServerLink link; BPrivate::AppServerLink link;
link.StartMessage(AS_GET_FONT_BOUNDING_BOX); link.StartMessage(AS_GET_FONT_BOUNDING_BOX);
link.Attach<uint16>(fFamilyID); link.Attach<uint16>(fFamilyID);
link.Attach<uint16>(fStyleID); link.Attach<uint16>(fStyleID);
int32 code;
if (link.FlushWithReply(code) != B_OK if (link.FlushWithReply(code) != B_OK
|| code != SERVER_TRUE) || code != B_OK)
return BRect(0, 0, 0 ,0); return BRect(0, 0, 0 ,0);
BRect box; BRect box;
@@ -734,15 +705,14 @@ BFont::FileFormat(void) const
int32 int32
BFont::CountTuned(void) const BFont::CountTuned(void) const
{ {
int32 code;
BPrivate::AppServerLink link; BPrivate::AppServerLink link;
link.StartMessage(AS_GET_TUNED_COUNT); link.StartMessage(AS_GET_TUNED_COUNT);
link.Attach<uint16>(fFamilyID); link.Attach<uint16>(fFamilyID);
link.Attach<uint16>(fStyleID); link.Attach<uint16>(fStyleID);
int32 code;
if (link.FlushWithReply(code) != B_OK if (link.FlushWithReply(code) != B_OK
|| code != SERVER_TRUE) || code != B_OK)
return -1; return -1;
int32 count; int32 count;
@@ -757,16 +727,15 @@ BFont::GetTunedInfo(int32 index, tuned_font_info *info) const
if (!info) if (!info)
return; return;
int32 code;
BPrivate::AppServerLink link; BPrivate::AppServerLink link;
link.StartMessage(AS_GET_TUNED_INFO); link.StartMessage(AS_GET_TUNED_INFO);
link.Attach<uint16>(fFamilyID); link.Attach<uint16>(fFamilyID);
link.Attach<uint16>(fStyleID); link.Attach<uint16>(fStyleID);
link.Attach<uint32>(index); link.Attach<uint32>(index);
int32 code;
if (link.FlushWithReply(code) != B_OK if (link.FlushWithReply(code) != B_OK
|| code != SERVER_TRUE) || code != B_OK)
return; return;
link.Read<tuned_font_info>(info); link.Read<tuned_font_info>(info);
@@ -778,9 +747,8 @@ BFont::TruncateString(BString *inOut, uint32 mode, float width) const
{ {
// NOTE: Careful, we cannot directly use "inOut->String()" as result // NOTE: Careful, we cannot directly use "inOut->String()" as result
// array, because the string length increases by 3 bytes in the worst case scenario. // array, because the string length increases by 3 bytes in the worst case scenario.
const char* array[1]; const char *string = inOut->String();
array[0] = inOut->String(); GetTruncatedStrings(&string, 1, mode, width, inOut);
GetTruncatedStrings(array, 1, mode, width, inOut);
} }
@@ -881,7 +849,7 @@ BFont::GetStringWidths(const char *stringArray[], const int32 lengthArray[],
} }
if (link.FlushWithReply(code) != B_OK if (link.FlushWithReply(code) != B_OK
|| code != SERVER_TRUE) || code != B_OK)
return; return;
link.Read(widthArray, sizeof(float) * numStrings); link.Read(widthArray, sizeof(float) * numStrings);
@@ -925,7 +893,7 @@ BFont::GetEscapements(const char charArray[], int32 numChars, escapement_delta *
link.Attach(charArray, bytesInBuffer); link.Attach(charArray, bytesInBuffer);
if (link.FlushWithReply(code) != B_OK if (link.FlushWithReply(code) != B_OK
|| code != SERVER_TRUE) || code != B_OK)
return; return;
link.Read(escapementArray, numChars * sizeof(float)); link.Read(escapementArray, numChars * sizeof(float));
@@ -975,7 +943,7 @@ BFont::GetEscapements(const char charArray[], int32 numChars, escapement_delta *
} }
if (link.FlushWithReply(code) != B_OK if (link.FlushWithReply(code) != B_OK
|| code != SERVER_TRUE) || code != B_OK)
return; return;
link.Read(escapementArray, sizeof(BPoint) * numChars); link.Read(escapementArray, sizeof(BPoint) * numChars);
@@ -999,7 +967,7 @@ BFont::GetEdges(const char charArray[], int32 numChars, edge_info edgeArray[]) c
link.Attach(charArray, bytesInBuffer); link.Attach(charArray, bytesInBuffer);
if (link.FlushWithReply(code) != B_OK if (link.FlushWithReply(code) != B_OK
|| code != SERVER_TRUE) || code != B_OK)
return; return;
link.Read(edgeArray, sizeof(edge_info) * numChars); link.Read(edgeArray, sizeof(edge_info) * numChars);
@@ -1023,7 +991,7 @@ BFont::GetHeight(font_height *_height) const
int32 code; int32 code;
if (link.FlushWithReply(code) != B_OK if (link.FlushWithReply(code) != B_OK
|| code != SERVER_TRUE) || code != B_OK)
return; return;
// Who put that "const" to this method? :-) // Who put that "const" to this method? :-)
@@ -1086,7 +1054,7 @@ BFont::_GetBoundingBoxes_(const char charArray[], int32 numChars, font_metric_mo
link.Attach(charArray, bytesInBuffer); link.Attach(charArray, bytesInBuffer);
if (link.FlushWithReply(code) != B_OK if (link.FlushWithReply(code) != B_OK
|| code != SERVER_TRUE) || code != B_OK)
return; return;
link.Read(boundingBoxArray, sizeof(BRect) * numChars); link.Read(boundingBoxArray, sizeof(BRect) * numChars);
@@ -1129,7 +1097,7 @@ BFont::GetBoundingBoxesForStrings(const char *stringArray[], int32 numStrings,
} }
if (link.FlushWithReply(code) != B_OK if (link.FlushWithReply(code) != B_OK
|| code != SERVER_TRUE) || code != B_OK)
return; return;
link.Read(boundingBoxArray, sizeof(BRect) * numStrings); link.Read(boundingBoxArray, sizeof(BRect) * numStrings);
@@ -1158,7 +1126,7 @@ BFont::GetGlyphShapes(const char charArray[], int32 numChars, BShape *glyphShape
link.Attach(charArray, numChars); link.Attach(charArray, numChars);
if (link.FlushWithReply(code) != B_OK if (link.FlushWithReply(code) != B_OK
|| code != SERVER_TRUE) || code != B_OK)
return; return;
for (int32 i = 0; i < numChars; i++) for (int32 i = 0; i < numChars; i++)
@@ -1185,7 +1153,7 @@ BFont::GetHasGlyphs(const char charArray[], int32 numChars, bool hasArray[]) con
link.Attach(charArray, bytesInBuffer); link.Attach(charArray, bytesInBuffer);
if (link.FlushWithReply(code) != B_OK if (link.FlushWithReply(code) != B_OK
|| code != SERVER_TRUE) || code != B_OK)
return; return;
link.Read(hasArray, sizeof(bool) * numChars); link.Read(hasArray, sizeof(bool) * numChars);
+27 -2
View File
@@ -129,6 +129,27 @@ FontStyle::Flags() const
} }
/*!
\brief Updates the given face to match the one from this style
The specified font face often doesn't match the exact face of
a style. This method will preserve the attributes of the face
that this style does not alter, and will only update the
attributes that matter to this style.
The font renderer could then emulate the other face attributes
taking this style as a base.
*/
uint16
FontStyle::PreservedFace(uint16 face) const
{
// TODO: make this better
face &= ~(B_REGULAR_FACE | B_BOLD_FACE | B_ITALIC_FACE);
face |= Face();
return face;
}
/*! /*!
\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
@@ -350,7 +371,7 @@ FontFamily::GetStyle(const char *styleName) const
FontStyle* FontStyle*
FontFamily::GetStyleWithID(uint16 id) const FontFamily::GetStyleByID(uint16 id) const
{ {
for (int32 i = 0; i < fStyles.CountItems(); i++) { for (int32 i = 0; i < fStyles.CountItems(); i++) {
FontStyle* style = fStyles.ItemAt(i); FontStyle* style = fStyles.ItemAt(i);
@@ -363,10 +384,14 @@ FontFamily::GetStyleWithID(uint16 id) const
FontStyle* FontStyle*
FontFamily::GetStyleWithFace(uint16 face) const FontFamily::GetStyleMatchingFace(uint16 face) const
{ {
// we currently only use bold/italic/regular faces
face &= B_BOLD_FACE | B_ITALIC_FACE | B_REGULAR_FACE;
for (int32 i = 0; i < fStyles.CountItems(); i++) { for (int32 i = 0; i < fStyles.CountItems(); i++) {
FontStyle* style = fStyles.ItemAt(i); FontStyle* style = fStyles.ItemAt(i);
if (style->Face() == face) if (style->Face() == face)
return style; return style;
} }
+101 -100
View File
@@ -9,12 +9,11 @@
/** Handles the largest part of the font subsystem */ /** Handles the largest part of the font subsystem */
#include <String.h>
#include <Directory.h> #include <Directory.h>
#include <Entry.h> #include <Entry.h>
#include <storage/Path.h> // specified to be able to build under Dano
#include <File.h> #include <File.h>
#include <Message.h> #include <Message.h>
#include <Path.h>
#include <String.h> #include <String.h>
#include <FontServer.h> #include <FontServer.h>
@@ -29,30 +28,33 @@ FontServer *gFontServer = NULL;
//#define PRINT_FONT_LIST //#define PRINT_FONT_LIST
#if 0
/*! /*!
\brief Access function to request a face via the FreeType font cache \brief Access function to request a face via the FreeType font cache
*/ */
/*static FT_Error static FT_Error
face_requester(FTC_FaceID face_id, FT_Library library, face_requester(FTC_FaceID face_id, FT_Library library,
FT_Pointer request_data, FT_Face *aface) FT_Pointer request_data, FT_Face *aface)
{ {
CachedFace face = (CachedFace) face_id; CachedFace face = (CachedFace) face_id;
return FT_New_Face(ftlib, face->file_path.String(), face->face_index,aface); return FT_New_Face(ftlib, face->file_path.String(), face->face_index,aface);
} }
*/ #endif
// #pragma mark - // #pragma mark -
//! Does basic set up so that directories can be scanned //! Does basic set up so that directories can be scanned
FontServer::FontServer(void) FontServer::FontServer()
: BLocker("font server lock"), : BLocker("font server lock"),
fFamilies(20), fFamilies(20),
fPlain(NULL), fPlain(NULL),
fBold(NULL), fBold(NULL),
fFixed(NULL) fFixed(NULL)
{ {
fInit = FT_Init_FreeType(&ftlib) == 0; fInitStatus = FT_Init_FreeType(&ftlib) == 0 ? B_OK : B_ERROR;
/* /*
Fire up the font caching subsystem. Fire up the font caching subsystem.
@@ -67,7 +69,7 @@ FontServer::FontServer(void)
//! Frees items allocated in the constructor and shuts down FreeType //! Frees items allocated in the constructor and shuts down FreeType
FontServer::~FontServer(void) FontServer::~FontServer()
{ {
FTC_Manager_Done(ftmanager); FTC_Manager_Done(ftmanager);
FT_Done_FreeType(ftlib); FT_Done_FreeType(ftlib);
@@ -78,12 +80,10 @@ FontServer::~FontServer(void)
\brief Counts the number of font families available \brief Counts the number of font families available
\return The number of unique font families currently available \return The number of unique font families currently available
*/ */
int32 FontServer::CountFamilies(void) int32
FontServer::CountFamilies(void)
{ {
if (fInit) return fFamilies.CountItems();
return fFamilies.CountItems();
return 0;
} }
@@ -118,65 +118,6 @@ FontServer::RemoveFamily(const char *familyName)
} }
const char*
FontServer::GetFamilyName(uint16 id) const
{
for (int32 i = 0; i < fFamilies.CountItems(); i++) {
FontFamily* family = (FontFamily*)fFamilies.ItemAt(i);
if (family && family->ID() == id)
return family->Name();
}
return NULL;
}
const char*
FontServer::GetStyleName(const char* familyName, uint16 id) const
{
FontStyle* style = GetStyle(familyName, id);
if (style != NULL)
return style->Name();
return NULL;
}
FontStyle*
FontServer::GetStyle(const char* familyName, uint16 id) const
{
FontFamily* family = GetFamily(familyName);
if (family != NULL)
return family->GetStyleWithID(id);
return NULL;
}
/*!
\brief Protected function which locates a FontFamily object
\param name The family to find
\return Pointer to the specified family or NULL if not found.
Do NOT delete the FontFamily returned by this function.
*/
FontFamily*
FontServer::GetFamily(const char* name) const
{
if (!fInit || name == NULL)
return NULL;
int32 count = fFamilies.CountItems();
for (int32 i = 0; i < count; i++) {
FontFamily *family = (FontFamily*)fFamilies.ItemAt(i);
if (!strcmp(family->Name(), name))
return family;
}
return NULL;
}
//! Scans the four default system font folders //! Scans the four default system font folders
void void
FontServer::ScanSystemFolders(void) FontServer::ScanSystemFolders(void)
@@ -396,28 +337,101 @@ FontServer::SaveList(void)
} }
/*! FontFamily*
\brief Retrieves the FontStyle object FontServer::GetFamilyByIndex(int32 index) const
\param family The font's family
\param style The font's style
\return The FontStyle having those attributes or NULL if not available
*/
FontStyle*
FontServer::GetStyle(const char* familyName, const char* styleName, uint16 face)
{ {
FontFamily* family = GetFamily(familyName); return fFamilies.ItemAt(index);
if (family) { }
if (styleName == NULL) {
// try to get from face
return family->GetStyleWithFace(face); /*!
} \brief Locates a FontFamily object by name
return family->GetStyle(styleName); \param name The family to find
\return Pointer to the specified family or NULL if not found.
*/
FontFamily*
FontServer::GetFamily(const char* name) const
{
if (name == NULL)
return NULL;
int32 count = fFamilies.CountItems();
for (int32 i = 0; i < count; i++) {
FontFamily* family = fFamilies.ItemAt(i);
if (!strcmp(family->Name(), name))
return family;
} }
return NULL; return NULL;
} }
FontFamily*
FontServer::GetFamily(uint16 familyID) const
{
for (int32 i = 0; i < fFamilies.CountItems(); i++) {
FontFamily *family = (FontFamily*)fFamilies.ItemAt(i);
if (family->ID() == familyID)
return family;
}
return NULL;
}
FontStyle*
FontServer::GetStyleByIndex(const char* familyName, int32 index) const
{
FontFamily* family = GetFamily(familyName);
if (family != NULL)
return family->StyleAt(index);
return NULL;
}
/*!
\brief Retrieves the FontStyle object that comes closest to the one specified
\param family The font's family or NULL in which case \a familyID is used
\param style The font's style or NULL in which case \a styleID is used
\param familyID will only be used if \a family is NULL (or empty)
\param styleID will only be used if \a style is NULL (or empty)
\param face is used to specify the style if both \a style is NULL or empty
and styleID is 0xffff.
\return The FontStyle having those attributes or NULL if not available
*/
FontStyle*
FontServer::GetStyle(const char* familyName, const char* styleName, uint16 familyID,
uint16 styleID, uint16 face)
{
FontFamily* family;
// find family
if (familyName != NULL && familyName[0])
family = GetFamily(familyName);
else
family = GetFamily(familyID);
if (family == NULL)
return NULL;
// find style
if (styleName != NULL && styleName[0])
return family->GetStyle(styleName);
if (styleID != 0xffff)
return family->GetStyleByID(styleID);
// try to get from face
return family->GetStyleMatchingFace(face);
}
/*! /*!
\brief Retrieves the FontStyle object \brief Retrieves the FontStyle object
\param family ID for the font's family \param family ID for the font's family
@@ -429,20 +443,7 @@ FontServer::GetStyle(uint16 familyID, uint16 styleID)
{ {
FontFamily *family = GetFamily(familyID); FontFamily *family = GetFamily(familyID);
if (family) if (family)
return family->GetStyleWithID(styleID); return family->GetStyleByID(styleID);
return NULL;
}
FontFamily*
FontServer::GetFamily(uint16 familyID) const
{
for (int32 i = 0; i < fFamilies.CountItems(); i++) {
FontFamily *family = (FontFamily*)fFamilies.ItemAt(i);
if (family->ID() == familyID)
return family;
}
return NULL; return NULL;
} }
+207 -234
View File
@@ -1108,6 +1108,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
break; break;
} }
/* font messages */
case AS_UPDATED_CLIENT_FONTLIST: case AS_UPDATED_CLIENT_FONTLIST:
{ {
STRACE(("ServerApp %s: Acknowledged update of client-side font list\n", STRACE(("ServerApp %s: Acknowledged update of client-side font list\n",
@@ -1160,28 +1162,26 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
{ {
FTRACE(("ServerApp %s: AS_GET_FAMILY_NAME\n", Signature())); FTRACE(("ServerApp %s: AS_GET_FAMILY_NAME\n", Signature()));
// Attached Data: // Attached Data:
// 1) int32 the ID of the font family to get // 1) int32 the index of the font family to get
// Returns: // Returns:
// 1) font_family - name of family // 1) font_family - name of family
// 2) uint32 - flags of font family (B_IS_FIXED || B_HAS_TUNED_FONT) // 2) uint32 - flags of font family (B_IS_FIXED || B_HAS_TUNED_FONT)
int32 id; int32 index;
link.Read<int32>(&id); link.Read<int32>(&index);
gFontServer->Lock(); gFontServer->Lock();
FontFamily *ffamily = gFontServer->GetFamily(id);
if (ffamily) {
font_family fam;
strncpy(fam, ffamily->Name(), sizeof(font_family) - 1);
fam[sizeof(font_family) - 1] = 0;
fLink.StartMessage(SERVER_TRUE);
fLink.Attach(fam, sizeof(font_family));
fLink.Attach<uint32>(ffamily->Flags());
} else
fLink.StartMessage(SERVER_FALSE);
fLink.Flush(); FontFamily *family = gFontServer->GetFamilyByIndex(index);
if (family) {
fLink.StartMessage(B_OK);
fLink.AttachString(family->Name());
fLink.Attach<uint32>(family->Flags());
} else
fLink.StartMessage(B_BAD_VALUE);
gFontServer->Unlock(); gFontServer->Unlock();
fLink.Flush();
break; break;
} }
case AS_GET_STYLE_NAME: case AS_GET_STYLE_NAME:
@@ -1189,34 +1189,30 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
FTRACE(("ServerApp %s: AS_GET_STYLE_NAME\n", Signature())); FTRACE(("ServerApp %s: AS_GET_STYLE_NAME\n", Signature()));
// Attached Data: // Attached Data:
// 1) font_family The name of the font family // 1) font_family The name of the font family
// 2) int32 ID of the style to get // 2) int32 index of the style to get
// Returns: // Returns:
// 1) font_style - name of the style // 1) font_style - name of the style
// 2) uint16 - appropriate face values // 2) uint16 - appropriate face values
// 3) uint32 - flags of font style (B_IS_FIXED || B_HAS_TUNED_FONT) // 3) uint32 - flags of font style (B_IS_FIXED || B_HAS_TUNED_FONT)
int32 styleid; font_family family;
font_family fam; int32 styleIndex;
link.ReadString(family, sizeof(font_family));
link.Read(fam, sizeof(font_family)); link.Read<int32>(&styleIndex);
link.Read<int32>(&styleid);
gFontServer->Lock(); gFontServer->Lock();
FontStyle *fstyle = gFontServer->GetStyle(fam, styleid); FontStyle *fontStyle = gFontServer->GetStyleByIndex(family, styleIndex);
if (fstyle) { if (fontStyle != NULL) {
font_style style; fLink.StartMessage(B_OK);
strncpy(style, fstyle->Name(), sizeof(font_style) - 1); fLink.AttachString(fontStyle->Name());
style[sizeof(font_style) - 1] = 0; fLink.Attach<uint16>(fontStyle->Face());
fLink.StartMessage(SERVER_TRUE); fLink.Attach<uint32>(fontStyle->Flags());
fLink.Attach(style, sizeof(font_style));
fLink.Attach<uint32>(fstyle->Face());
fLink.Attach<uint32>(fstyle->Flags());
} else } else
fLink.StartMessage(SERVER_FALSE); fLink.StartMessage(B_BAD_VALUE);
fLink.Flush();
gFontServer->Unlock(); gFontServer->Unlock();
fLink.Flush();
break; break;
} }
case AS_GET_FAMILY_AND_STYLE: case AS_GET_FAMILY_AND_STYLE:
@@ -1265,31 +1261,23 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
// Returns: // Returns:
// 1) font_direction direction of font // 1) font_direction direction of font
// NOTE: While this may be unimplemented, we can safely return int32 familyID, styleID;
// SERVER_FALSE. This will force the BFont code to default to link.Read<int32>(&familyID);
// B_LEFT_TO_RIGHT, which is what the vast majority of fonts will be. link.Read<int32>(&styleID);
// TODO: This will be fixed later.
int32 famid, styid; gFontServer->Lock();
link.Read<int32>(&famid);
link.Read<int32>(&styid); FontStyle *fontStyle = gFontServer->GetStyle(familyID, styleID);
if (fontStyle) {
/* gFontServer->Lock(); font_direction direction = fontStyle->Direction();
FontStyle *fstyle=gFontServer->GetStyle(famid,styid);
if(fstyle) fLink.StartMessage(B_OK);
{ fLink.Attach<font_direction>(direction);
font_direction dir=fstyle->GetDirection(); } else
fLink.StartMessage(B_BAD_VALUE);
fLink.StartMessage(SERVER_TRUE);
fLink.Attach<font_direction>(dir); gFontServer->Unlock();
fLink.Flush(); fLink.Flush();
}
else
{
*/ fLink.StartMessage(SERVER_FALSE);
fLink.Flush();
// }
// gFontServer->Unlock();
break; break;
} }
case AS_GET_STRING_WIDTHS: case AS_GET_STRING_WIDTHS:
@@ -1303,10 +1291,10 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
// 5) int32 numStrings // 5) int32 numStrings
// 6) int32 string length to measure (numStrings times) // 6) int32 string length to measure (numStrings times)
// 7) string String to measure (numStrings times) // 7) string String to measure (numStrings times)
// Returns: // Returns:
// 1) float - width of the string in pixels (numStrings times) // 1) float - width of the string in pixels (numStrings times)
uint16 family, style; uint16 family, style;
float size; float size;
uint8 spacing; uint8 spacing;
@@ -1322,10 +1310,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
int32 lengthArray[numStrings]; int32 lengthArray[numStrings];
char *stringArray[numStrings]; char *stringArray[numStrings];
for (int32 i = 0; i < numStrings; i++) { for (int32 i = 0; i < numStrings; i++) {
// TODO: the length is actually encoded twice here
// It would be nicer to only send as much from the string as needed
link.Read<int32>(&lengthArray[i]); link.Read<int32>(&lengthArray[i]);
#ifdef DE_OLD_READ_STRING
stringArray[i] = new char[lengthArray[i]];
#endif
link.ReadString(&stringArray[i]); link.ReadString(&stringArray[i]);
} }
@@ -1347,21 +1334,16 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
// actually works. It is about 20 times faster! // actually works. It is about 20 times faster!
//width = font.StringWidth(string, length); //width = font.StringWidth(string, length);
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(B_OK);
fLink.Attach(widthArray, sizeof(widthArray)); fLink.Attach(widthArray, sizeof(widthArray));
} else } else
fLink.StartMessage(SERVER_FALSE); fLink.StartMessage(B_BAD_VALUE);
fLink.Flush(); fLink.Flush();
#ifndef DE_NEW_READ_STRING
for (int32 i = 0; i < numStrings; i++) { for (int32 i = 0; i < numStrings; i++) {
#ifndef DE_OLD_READ_STRING
free(stringArray[i]); free(stringArray[i]);
#else
delete[] stringArray[i];
#endif
} }
#endif
break; break;
} }
case AS_GET_FONT_BOUNDING_BOX: case AS_GET_FONT_BOUNDING_BOX:
@@ -1376,7 +1358,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
// 1) BRect - box holding entire font // 1) BRect - box holding entire font
// ToDo: implement me! // ToDo: implement me!
fLink.StartMessage(SERVER_FALSE); fLink.StartMessage(B_ERROR);
fLink.Flush(); fLink.Flush();
break; break;
} }
@@ -1389,20 +1371,21 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
// Returns: // Returns:
// 1) int32 - number of font strikes available // 1) int32 - number of font strikes available
uint16 famid, styid; uint16 familyID, styleID;
link.Read<uint16>(&famid); link.Read<uint16>(&familyID);
link.Read<uint16>(&styid); link.Read<uint16>(&styleID);
gFontServer->Lock(); gFontServer->Lock();
FontStyle *fstyle = gFontServer->GetStyle(famid, styid);
if (fstyle) {
fLink.StartMessage(SERVER_TRUE);
fLink.Attach<int32>(fstyle->TunedCount());
} else
fLink.StartMessage(SERVER_FALSE);
fLink.Flush(); FontStyle *fontStyle = gFontServer->GetStyle(familyID, styleID);
if (fontStyle != NULL) {
fLink.StartMessage(B_OK);
fLink.Attach<int32>(fontStyle->TunedCount());
} else
fLink.StartMessage(B_BAD_VALUE);
gFontServer->Unlock(); gFontServer->Unlock();
fLink.Flush();
break; break;
} }
case AS_GET_TUNED_INFO: case AS_GET_TUNED_INFO:
@@ -1417,7 +1400,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
// Returns: // Returns:
// 1) tuned_font_info - info on the strike specified // 1) tuned_font_info - info on the strike specified
// ToDo: implement me! // ToDo: implement me!
fLink.StartMessage(SERVER_FALSE); fLink.StartMessage(B_ERROR);
fLink.Flush(); fLink.Flush();
break; break;
} }
@@ -1431,20 +1414,21 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
// Returns: // Returns:
// 1) bool - font is/is not fixed // 1) bool - font is/is not fixed
uint16 famid, styid; uint16 familyID, styleID;
link.Read<uint16>(&famid); link.Read<uint16>(&familyID);
link.Read<uint16>(&styid); link.Read<uint16>(&styleID);
gFontServer->Lock(); gFontServer->Lock();
FontStyle *fstyle = gFontServer->GetStyle(famid, styid);
if (fstyle) {
fLink.StartMessage(SERVER_TRUE);
fLink.Attach<bool>(fstyle->IsFixedWidth());
} else
fLink.StartMessage(SERVER_FALSE);
fLink.Flush(); FontStyle *fontStyle = gFontServer->GetStyle(familyID, styleID);
if (fontStyle != NULL) {
fLink.StartMessage(B_OK);
fLink.Attach<bool>(fontStyle->IsFixedWidth());
} else
fLink.StartMessage(B_BAD_VALUE);
gFontServer->Unlock(); gFontServer->Unlock();
fLink.Flush();
break; break;
} }
case AS_SET_FAMILY_AND_STYLE: case AS_SET_FAMILY_AND_STYLE:
@@ -1454,7 +1438,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
// Attached Data: // Attached Data:
// 1) font_family - name of font family to use // 1) font_family - name of font family to use
// 2) font_style - name of style in family // 2) font_style - name of style in family
// 3) face - the font's current face // 3) family ID - only used if 1) is empty
// 4) style ID - only used if 2) is empty
// 5) face - the font's current face
// Returns: // Returns:
// 1) uint16 - family ID // 1) uint16 - family ID
@@ -1463,21 +1449,31 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
font_family family; font_family family;
font_style style; font_style style;
uint16 familyID, styleID;
uint16 face; uint16 face;
if (link.ReadString(family, sizeof(font_family)) == B_OK if (link.ReadString(family, sizeof(font_family)) == B_OK
&& link.ReadString(style, sizeof(font_style)) == B_OK && link.ReadString(style, sizeof(font_style)) == B_OK
&& link.Read<uint16>(&familyID) == B_OK
&& link.Read<uint16>(&styleID) == B_OK
&& link.Read<uint16>(&face) == B_OK) { && link.Read<uint16>(&face) == B_OK) {
// get the font and return IDs and face // get the font and return IDs and face
gFontServer->Lock(); gFontServer->Lock();
FontStyle *fontStyle = gFontServer->GetStyle(family[0] ? family : NULL,
style[0] ? style : NULL, face); FontStyle *fontStyle = gFontServer->GetStyle(family, style,
familyID, styleID, face);
if (fontStyle != NULL) { if (fontStyle != NULL) {
fLink.StartMessage(B_OK); fLink.StartMessage(B_OK);
fLink.Attach<uint16>(fontStyle->Family()->ID()); fLink.Attach<uint16>(fontStyle->Family()->ID());
fLink.Attach<uint16>(fontStyle->ID()); fLink.Attach<uint16>(fontStyle->ID());
fLink.Attach<uint16>(fontStyle->Face());
// we try to keep the font face close to what we got
face = fontStyle->PreservedFace(face);
fLink.Attach<uint16>(face);
} else } else
fLink.StartMessage(B_NAME_NOT_FOUND); fLink.StartMessage(B_NAME_NOT_FOUND);
gFontServer->Unlock(); gFontServer->Unlock();
} else } else
fLink.StartMessage(B_BAD_VALUE); fLink.StartMessage(B_BAD_VALUE);
@@ -1485,49 +1481,6 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
fLink.Flush(); fLink.Flush();
break; break;
} }
case AS_SET_FAMILY_AND_STYLE_FROM_ID:
{
FTRACE(("ServerApp %s: AS_SET_FAMILY_AND_STYLE_FROM_ID\n",
Signature()));
// Attached Data:
// 1) uint16 - ID of font family to use
// 2) uint16 - ID of style in family
// Returns:
// 1) uint16 - face of the font
uint16 fam, sty;
link.Read<uint16>(&fam);
link.Read<uint16>(&sty);
ServerFont font;
if (font.SetFamilyAndStyle(fam, sty) == B_OK) {
fLink.StartMessage(SERVER_TRUE);
fLink.Attach<uint16>(font.Face());
} else
fLink.StartMessage(SERVER_FALSE);
fLink.Flush();
break;
}
case AS_SET_FAMILY_AND_FACE:
{
FTRACE(("ServerApp %s: AS_SET_FAMILY_AND_FACE unimplmemented\n",
Signature()));
// Attached Data:
// 1) font_family - name of font family to use
// 2) uint16 - font face
// Returns:
// 1) uint16 - family ID
// 2) uint16 - style ID
// TODO: Check R5 for error condition behavior in SET_FAMILY_AND_FACE
// ToDo: implement me!
fLink.StartMessage(SERVER_FALSE);
fLink.Flush();
break;
}
case AS_COUNT_FONT_FAMILIES: case AS_COUNT_FONT_FAMILIES:
{ {
FTRACE(("ServerApp %s: AS_COUNT_FONT_FAMILIES\n", Signature())); FTRACE(("ServerApp %s: AS_COUNT_FONT_FAMILIES\n", Signature()));
@@ -1536,7 +1489,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
gFontServer->Lock(); gFontServer->Lock();
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(B_OK);
fLink.Attach<int32>(gFontServer->CountFamilies()); fLink.Attach<int32>(gFontServer->CountFamilies());
fLink.Flush(); fLink.Flush();
@@ -1551,19 +1504,20 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
// Returns: // Returns:
// 1) int32 - # of font styles // 1) int32 - # of font styles
font_family fam; font_family familyName;
link.Read(fam,sizeof(font_family)); link.ReadString(familyName, sizeof(font_family));
gFontServer->Lock(); gFontServer->Lock();
FontFamily *ffam = gFontServer->GetFamily(fam);
if (ffam) {
fLink.StartMessage(SERVER_TRUE);
fLink.Attach<int32>(ffam->CountStyles());
} else
fLink.StartMessage(SERVER_FALSE);
fLink.Flush(); FontFamily *family = gFontServer->GetFamily(familyName);
if (family != NULL) {
fLink.StartMessage(B_OK);
fLink.Attach<int32>(family->CountStyles());
} else
fLink.StartMessage(B_BAD_VALUE);
gFontServer->Unlock(); gFontServer->Unlock();
fLink.Flush();
break; break;
} }
case AS_SET_SYSFONT_PLAIN: case AS_SET_SYSFONT_PLAIN:
@@ -1579,26 +1533,32 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
// 5) uint32 - font flags // 5) uint32 - font flags
gFontServer->Lock(); gFontServer->Lock();
ServerFont *sf = NULL;
ServerFont *font = NULL;
switch (code) { switch (code) {
case AS_SET_SYSFONT_PLAIN: sf = gFontServer->GetSystemPlain(); break; case AS_SET_SYSFONT_PLAIN:
case AS_SET_SYSFONT_BOLD: sf = gFontServer->GetSystemBold(); break; font = gFontServer->GetSystemPlain();
case AS_SET_SYSFONT_FIXED: sf = gFontServer->GetSystemFixed(); break; break;
case AS_SET_SYSFONT_BOLD:
font = gFontServer->GetSystemBold();
break;
case AS_SET_SYSFONT_FIXED:
font = gFontServer->GetSystemFixed();
break;
} }
if (sf) { if (font != NULL) {
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(B_OK);
fLink.Attach<uint16>(sf->FamilyID()); fLink.Attach<uint16>(font->FamilyID());
fLink.Attach<uint16>(sf->StyleID()); fLink.Attach<uint16>(font->StyleID());
fLink.Attach<float>(sf->Size()); fLink.Attach<float>(font->Size());
fLink.Attach<uint16>(sf->Face()); fLink.Attach<uint16>(font->Face());
fLink.Attach<uint32>(sf->Flags()); fLink.Attach<uint32>(font->Flags());
} else } else
fLink.StartMessage(SERVER_FALSE); fLink.StartMessage(B_BAD_VALUE);
fLink.Flush();
gFontServer->Unlock(); gFontServer->Unlock();
fLink.Flush();
break; break;
} }
case AS_GET_FONT_HEIGHT: case AS_GET_FONT_HEIGHT:
@@ -1608,22 +1568,23 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
// 1) uint16 family ID // 1) uint16 family ID
// 2) uint16 style ID // 2) uint16 style ID
// 3) float size // 3) float size
uint16 famid,styid; uint16 familyID, styleID;
float ptsize; float size;
link.Read<uint16>(&famid); link.Read<uint16>(&familyID);
link.Read<uint16>(&styid); link.Read<uint16>(&styleID);
link.Read<float>(&ptsize); link.Read<float>(&size);
gFontServer->Lock(); gFontServer->Lock();
FontStyle *fstyle = gFontServer->GetStyle(famid, styid);
if (fstyle) {
fLink.StartMessage(SERVER_TRUE);
fLink.Attach<font_height>(fstyle->GetHeight(ptsize));
} else
fLink.StartMessage(SERVER_FALSE);
fLink.Flush(); FontStyle *fontStyle = gFontServer->GetStyle(familyID, styleID);
if (fontStyle != NULL) {
fLink.StartMessage(B_OK);
fLink.Attach<font_height>(fontStyle->GetHeight(size));
} else
fLink.StartMessage(B_BAD_VALUE);
gFontServer->Unlock(); gFontServer->Unlock();
fLink.Flush();
break; break;
} }
case AS_GET_GLYPH_SHAPES: case AS_GET_GLYPH_SHAPES:
@@ -1643,33 +1604,34 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
// 1) BShape - glyph shape // 1) BShape - glyph shape
// numChars times // numChars times
uint16 famid, styid; uint16 familyID, styleID;
uint32 flags; uint32 flags;
float ptsize, shear, rotation; float size, shear, rotation;
link.Read<uint16>(&famid); link.Read<uint16>(&familyID);
link.Read<uint16>(&styid); link.Read<uint16>(&styleID);
link.Read<float>(&ptsize); link.Read<float>(&size);
link.Read<float>(&shear); link.Read<float>(&shear);
link.Read<float>(&rotation); link.Read<float>(&rotation);
link.Read<uint32>(&flags); link.Read<uint32>(&flags);
int32 numChars; int32 numChars;
link.Read<int32>(&numChars); link.Read<int32>(&numChars);
char charArray[numChars]; char charArray[numChars];
link.Read(&charArray, numChars); link.Read(&charArray, numChars);
ServerFont font; ServerFont font;
if (font.SetFamilyAndStyle(famid, styid) == B_OK) { status_t status = font.SetFamilyAndStyle(familyID, styleID);
font.SetSize(ptsize); if (status == B_OK) {
font.SetSize(size);
font.SetShear(shear); font.SetShear(shear);
font.SetRotation(rotation); font.SetRotation(rotation);
font.SetFlags(flags); font.SetFlags(flags);
BShape **shapes = font.GetGlyphShapes(charArray, numChars); BShape **shapes = font.GetGlyphShapes(charArray, numChars);
if (shapes) { if (shapes) {
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(B_OK);
for (int32 i = 0; i < numChars; i++) { for (int32 i = 0; i < numChars; i++) {
fLink.AttachShape(*shapes[i]); fLink.AttachShape(*shapes[i]);
delete shapes[i]; delete shapes[i];
@@ -1677,9 +1639,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
delete shapes; delete shapes;
} else } else
fLink.StartMessage(SERVER_FALSE); fLink.StartMessage(B_ERROR);
} else } else
fLink.StartMessage(SERVER_FALSE); fLink.StartMessage(status);
fLink.Flush(); fLink.Flush();
break; break;
@@ -1693,27 +1655,31 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
// 3) int32 - numChars // 3) int32 - numChars
// 4) int32 - numBytes // 4) int32 - numBytes
// 5) char - the char buffer with size numBytes // 5) char - the char buffer with size numBytes
uint16 famid, styid; uint16 familyID, styleID;
link.Read<uint16>(&famid); link.Read<uint16>(&familyID);
link.Read<uint16>(&styid); link.Read<uint16>(&styleID);
int32 numChars; int32 numChars;
link.Read<int32>(&numChars); link.Read<int32>(&numChars);
uint32 numBytes; uint32 numBytes;
link.Read<uint32>(&numBytes); link.Read<uint32>(&numBytes);
char* charArray = new char[numBytes]; char* charArray = new char[numBytes];
link.Read(charArray, numBytes); link.Read(charArray, numBytes);
ServerFont font; ServerFont font;
if (font.SetFamilyAndStyle(famid, styid) == B_OK) { status_t status = font.SetFamilyAndStyle(familyID, styleID);
if (status == B_OK) {
bool hasArray[numChars]; bool hasArray[numChars];
font.GetHasGlyphs(charArray, numChars, hasArray); font.GetHasGlyphs(charArray, numChars, hasArray);
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(B_OK);
fLink.Attach(hasArray, sizeof(hasArray)); fLink.Attach(hasArray, sizeof(hasArray));
} else } else
fLink.StartMessage(SERVER_FALSE); fLink.StartMessage(status);
delete[] charArray;
fLink.Flush(); fLink.Flush();
break; break;
} }
@@ -1727,9 +1693,10 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
// 4) int32 - numBytes // 4) int32 - numBytes
// 5) char - the char buffer with size numBytes // 5) char - the char buffer with size numBytes
uint16 famid, styid; uint16 familyID, styleID;
link.Read<uint16>(&famid); link.Read<uint16>(&familyID);
link.Read<uint16>(&styid); link.Read<uint16>(&styleID);
int32 numChars; int32 numChars;
link.Read<int32>(&numChars); link.Read<int32>(&numChars);
@@ -1737,15 +1704,19 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
link.Read<uint32>(&numBytes); link.Read<uint32>(&numBytes);
char* charArray = new char[numBytes]; char* charArray = new char[numBytes];
link.Read(charArray, numBytes); link.Read(charArray, numBytes);
ServerFont font; ServerFont font;
if (font.SetFamilyAndStyle(famid, styid) == B_OK) { status_t status = font.SetFamilyAndStyle(familyID, styleID);
if (status == B_OK) {
edge_info edgeArray[numChars]; edge_info edgeArray[numChars];
font.GetEdges(charArray, numChars, edgeArray); font.GetEdges(charArray, numChars, edgeArray);
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(B_OK);
fLink.Attach(edgeArray, sizeof(edgeArray)); fLink.Attach(edgeArray, sizeof(edgeArray));
} else } else
fLink.StartMessage(SERVER_FALSE); fLink.StartMessage(status);
delete[] charArray;
fLink.Flush(); fLink.Flush();
break; break;
} }
@@ -1766,13 +1737,13 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
// 1) BPoint - escapement // 1) BPoint - escapement
// numChars times // numChars times
uint16 famid, styid; uint16 familyID, styleID;
uint32 flags; uint32 flags;
float ptsize, rotation; float size, rotation;
link.Read<uint16>(&famid); link.Read<uint16>(&familyID);
link.Read<uint16>(&styid); link.Read<uint16>(&styleID);
link.Read<float>(&ptsize); link.Read<float>(&size);
link.Read<float>(&rotation); link.Read<float>(&rotation);
link.Read<uint32>(&flags); link.Read<uint32>(&flags);
@@ -1787,23 +1758,24 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
} }
ServerFont font; ServerFont font;
if (font.SetFamilyAndStyle(famid, styid) == B_OK) { status_t status = font.SetFamilyAndStyle(familyID, styleID);
font.SetSize(ptsize); if (status == B_OK) {
font.SetSize(size);
font.SetRotation(rotation); font.SetRotation(rotation);
font.SetFlags(flags); font.SetFlags(flags);
BPoint *esc = font.GetEscapements(charArray, numChars, offsetArray); BPoint *escapements = font.GetEscapements(charArray, numChars, offsetArray);
if (esc) { if (escapements) {
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(B_OK);
for (int32 i = 0; i < numChars; i++) { for (int32 i = 0; i < numChars; i++) {
fLink.Attach<BPoint>(esc[i]); fLink.Attach<BPoint>(escapements[i]);
} }
delete esc; delete escapements;
} else } else
fLink.StartMessage(SERVER_FALSE); fLink.StartMessage(B_ERROR);
} else } else
fLink.StartMessage(SERVER_FALSE); fLink.StartMessage(status);
fLink.Flush(); fLink.Flush();
break; break;
@@ -1828,13 +1800,13 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
// Returns: // Returns:
// 1) float - escapement buffer with numChar entries // 1) float - escapement buffer with numChar entries
uint16 famid, styid; uint16 familyID, styleID;
uint32 flags; uint32 flags;
float ptsize, rotation; float size, rotation;
link.Read<uint16>(&famid); link.Read<uint16>(&familyID);
link.Read<uint16>(&styid); link.Read<uint16>(&styleID);
link.Read<float>(&ptsize); link.Read<float>(&size);
link.Read<float>(&rotation); link.Read<float>(&rotation);
link.Read<uint32>(&flags); link.Read<uint32>(&flags);
@@ -1847,32 +1819,32 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
uint32 numBytes; uint32 numBytes;
link.Read<uint32>(&numBytes); link.Read<uint32>(&numBytes);
char* charArray = new char[numBytes]; char* charArray = new char[numBytes];
link.Read(charArray, numBytes); link.Read(charArray, numBytes);
float* escapements = new float[numChars]; float* escapements = new float[numChars];
// figure out escapements // figure out escapements
ServerFont font; ServerFont font;
bool success = false; status_t status = font.SetFamilyAndStyle(familyID, styleID);
if (font.SetFamilyAndStyle(famid, styid) == B_OK) { if (status == B_OK) {
font.SetSize(ptsize); font.SetSize(size);
font.SetRotation(rotation); font.SetRotation(rotation);
font.SetFlags(flags); font.SetFlags(flags);
if (font.GetEscapements(charArray, numChars, escapements, delta)) { if (font.GetEscapements(charArray, numChars, escapements, delta)) {
fLink.StartMessage(SERVER_TRUE); fLink.StartMessage(B_OK);
fLink.Attach(escapements, numChars * sizeof(float)); fLink.Attach(escapements, numChars * sizeof(float));
success = true; } else
} status = B_ERROR;
} }
delete[] charArray; delete[] charArray;
delete[] escapements; delete[] escapements;
if (!success) if (status != B_OK)
fLink.StartMessage(SERVER_FALSE); fLink.StartMessage(status);
fLink.Flush(); fLink.Flush();
break; break;
@@ -2033,6 +2005,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
fLink.Flush(); fLink.Flush();
break; break;
} }
case AS_SCREEN_GET_MODE: case AS_SCREEN_GET_MODE:
{ {
STRACE(("ServerApp %s: AS_SCREEN_GET_MODE\n", Signature())); STRACE(("ServerApp %s: AS_SCREEN_GET_MODE\n", Signature()));