app_server FontManager: load all fonts and named-variants from a file
BFont::LoadFont can now use an index (0-based) and an optional named-instance (1-based) to select the font variant from a file. BFont::LoadFont can also use an index when loading from memory. Change-Id: I0ce3eb6cc77d32cf43847416561eafe3063ca693 Reviewed-on: https://review.haiku-os.org/c/haiku/+/7402 Reviewed-by: Jérôme Duval <[email protected]> Reviewed-by: Máximo Castañeda <[email protected]> Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
committed by
Máximo Castañeda
parent
fe8f7e314e
commit
d0f06357f5
@@ -283,8 +283,11 @@ public:
|
|||||||
void PrintToStream() const;
|
void PrintToStream() const;
|
||||||
|
|
||||||
status_t LoadFont(const char* path);
|
status_t LoadFont(const char* path);
|
||||||
|
status_t LoadFont(const char* path, uint16 index, uint16 instance);
|
||||||
status_t LoadFont(const area_id fontAreaID,
|
status_t LoadFont(const area_id fontAreaID,
|
||||||
size_t size = 0, size_t offset = 0);
|
size_t size = 0, size_t offset = 0);
|
||||||
|
status_t LoadFont(const area_id fontAreaID,
|
||||||
|
size_t size = 0, size_t offset = 0, uint16 index = 0);
|
||||||
status_t UnloadFont();
|
status_t UnloadFont();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -1458,10 +1458,19 @@ BFont::_GetExtraFlags() const
|
|||||||
|
|
||||||
status_t
|
status_t
|
||||||
BFont::LoadFont(const char* path)
|
BFont::LoadFont(const char* path)
|
||||||
|
{
|
||||||
|
return LoadFont(path, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BFont::LoadFont(const char* path, uint16 index, uint16 instance)
|
||||||
{
|
{
|
||||||
BPrivate::AppServerLink link;
|
BPrivate::AppServerLink link;
|
||||||
link.StartMessage(AS_ADD_FONT_FILE);
|
link.StartMessage(AS_ADD_FONT_FILE);
|
||||||
link.AttachString(path);
|
link.AttachString(path);
|
||||||
|
link.Attach<uint16>(index);
|
||||||
|
link.Attach<uint16>(instance);
|
||||||
status_t status = B_ERROR;
|
status_t status = B_ERROR;
|
||||||
if (link.FlushWithReply(status) != B_OK || status != B_OK) {
|
if (link.FlushWithReply(status) != B_OK || status != B_OK) {
|
||||||
return status;
|
return status;
|
||||||
@@ -1479,6 +1488,13 @@ BFont::LoadFont(const char* path)
|
|||||||
|
|
||||||
status_t
|
status_t
|
||||||
BFont::LoadFont(const area_id fontAreaID, size_t size, size_t offset)
|
BFont::LoadFont(const area_id fontAreaID, size_t size, size_t offset)
|
||||||
|
{
|
||||||
|
return LoadFont(fontAreaID, size, offset, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BFont::LoadFont(const area_id fontAreaID, size_t size, size_t offset, uint16 index)
|
||||||
{
|
{
|
||||||
BPrivate::AppServerLink link;
|
BPrivate::AppServerLink link;
|
||||||
|
|
||||||
@@ -1487,6 +1503,7 @@ BFont::LoadFont(const area_id fontAreaID, size_t size, size_t offset)
|
|||||||
link.Attach<int32>(fontAreaID);
|
link.Attach<int32>(fontAreaID);
|
||||||
link.Attach<size_t>(size);
|
link.Attach<size_t>(size);
|
||||||
link.Attach<size_t>(offset);
|
link.Attach<size_t>(offset);
|
||||||
|
link.Attach<uint16>(index);
|
||||||
|
|
||||||
status_t status = B_ERROR;
|
status_t status = B_ERROR;
|
||||||
if (link.FlushWithReply(status) != B_OK || status != B_OK) {
|
if (link.FlushWithReply(status) != B_OK || status != B_OK) {
|
||||||
|
|||||||
@@ -1581,6 +1581,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
|
|
||||||
// Attached Data:
|
// Attached Data:
|
||||||
// 1) char* - path to font on disk
|
// 1) char* - path to font on disk
|
||||||
|
// 2) uint16 - index in font file
|
||||||
|
// 3) uint16 - instance
|
||||||
|
|
||||||
// Returns:
|
// Returns:
|
||||||
// 1) uint16 - family ID of added font
|
// 1) uint16 - family ID of added font
|
||||||
@@ -1597,9 +1599,12 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
|
|
||||||
uint16 familyID, styleID;
|
uint16 familyID, styleID;
|
||||||
char* fontPath;
|
char* fontPath;
|
||||||
|
uint16 index, instance;
|
||||||
link.ReadString(&fontPath);
|
link.ReadString(&fontPath);
|
||||||
|
link.Read<uint16>(&index);
|
||||||
|
link.Read<uint16>(&instance);
|
||||||
|
|
||||||
status_t status = fAppFontManager->AddUserFontFromFile(fontPath,
|
status_t status = fAppFontManager->AddUserFontFromFile(fontPath, index, instance,
|
||||||
familyID, styleID);
|
familyID, styleID);
|
||||||
|
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
@@ -1632,6 +1637,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
// 1) area_id - id of memory area where font resides
|
// 1) area_id - id of memory area where font resides
|
||||||
// 2) size_t - size of memory area for font
|
// 2) size_t - size of memory area for font
|
||||||
// 3) size_t - offset to start of font memory
|
// 3) size_t - offset to start of font memory
|
||||||
|
// 4) uint16 - index in font buffer
|
||||||
|
|
||||||
// Returns:
|
// Returns:
|
||||||
// 1) uint16 - family ID of added font
|
// 1) uint16 - family ID of added font
|
||||||
@@ -1650,10 +1656,12 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
area_info fontAreaInfo;
|
area_info fontAreaInfo;
|
||||||
char* area_addr;
|
char* area_addr;
|
||||||
size_t size, offset;
|
size_t size, offset;
|
||||||
|
uint16 index;
|
||||||
|
|
||||||
link.Read<int32>(&fontAreaID);
|
link.Read<int32>(&fontAreaID);
|
||||||
link.Read<size_t>(&size);
|
link.Read<size_t>(&size);
|
||||||
link.Read<size_t>(&offset);
|
link.Read<size_t>(&offset);
|
||||||
|
link.Read<uint16>(&index);
|
||||||
fontAreaCloneID = clone_area("user font",
|
fontAreaCloneID = clone_area("user font",
|
||||||
(void **)&area_addr,
|
(void **)&area_addr,
|
||||||
B_ANY_ADDRESS,
|
B_ANY_ADDRESS,
|
||||||
@@ -1702,7 +1710,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
|
|
||||||
uint16 familyID, styleID;
|
uint16 familyID, styleID;
|
||||||
|
|
||||||
status = fAppFontManager->AddUserFontFromMemory(fontData, size,
|
status = fAppFontManager->AddUserFontFromMemory(fontData, size, index,
|
||||||
familyID, styleID);
|
familyID, styleID);
|
||||||
|
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
|
|||||||
@@ -68,6 +68,8 @@ class ServerFont {
|
|||||||
const char* Family() const;
|
const char* Family() const;
|
||||||
const char* Path() const
|
const char* Path() const
|
||||||
{ return fStyle->Path(); }
|
{ return fStyle->Path(); }
|
||||||
|
long FaceIndex() const
|
||||||
|
{ return fStyle->FreeTypeFace()->face_index; }
|
||||||
|
|
||||||
void SetStyle(FontStyle* style);
|
void SetStyle(FontStyle* style);
|
||||||
status_t SetFamilyAndStyle(uint16 familyID,
|
status_t SetFamilyAndStyle(uint16 familyID,
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ AppFontManager::AppFontManager()
|
|||||||
/*! \brief Adds the FontFamily/FontStyle that is represented by this path.
|
/*! \brief Adds the FontFamily/FontStyle that is represented by this path.
|
||||||
*/
|
*/
|
||||||
status_t
|
status_t
|
||||||
AppFontManager::AddUserFontFromFile(const char* path,
|
AppFontManager::AddUserFontFromFile(const char* path, uint16 index, uint16 instance,
|
||||||
uint16& familyID, uint16& styleID)
|
uint16& familyID, uint16& styleID)
|
||||||
{
|
{
|
||||||
ASSERT(IsLocked());
|
ASSERT(IsLocked());
|
||||||
@@ -66,12 +66,11 @@ AppFontManager::AddUserFontFromFile(const char* path,
|
|||||||
return status;
|
return status;
|
||||||
|
|
||||||
FT_Face face;
|
FT_Face face;
|
||||||
FT_Error error = FT_New_Face(gFreeTypeLibrary, path, 0, &face);
|
FT_Error error = FT_New_Face(gFreeTypeLibrary, path, index | (instance << 16), &face);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
status = _AddFont(face, nodeRef, path, familyID, styleID);
|
status = _AddFont(face, nodeRef, path, familyID, styleID);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,7 +78,7 @@ AppFontManager::AddUserFontFromFile(const char* path,
|
|||||||
/*! \brief Adds the FontFamily/FontStyle that is represented by the area in memory.
|
/*! \brief Adds the FontFamily/FontStyle that is represented by the area in memory.
|
||||||
*/
|
*/
|
||||||
status_t
|
status_t
|
||||||
AppFontManager::AddUserFontFromMemory(const FT_Byte* fontAddress, size_t size,
|
AppFontManager::AddUserFontFromMemory(const FT_Byte* fontAddress, size_t size, uint16 index,
|
||||||
uint16& familyID, uint16& styleID)
|
uint16& familyID, uint16& styleID)
|
||||||
{
|
{
|
||||||
ASSERT(IsLocked());
|
ASSERT(IsLocked());
|
||||||
@@ -88,7 +87,7 @@ AppFontManager::AddUserFontFromMemory(const FT_Byte* fontAddress, size_t size,
|
|||||||
status_t status;
|
status_t status;
|
||||||
|
|
||||||
FT_Face face;
|
FT_Face face;
|
||||||
FT_Error error = FT_New_Memory_Face(gFreeTypeLibrary, fontAddress, size, 0,
|
FT_Error error = FT_New_Memory_Face(gFreeTypeLibrary, fontAddress, size, index,
|
||||||
&face);
|
&face);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|||||||
@@ -37,10 +37,10 @@ public:
|
|||||||
void Unlock() { BLocker::Unlock(); }
|
void Unlock() { BLocker::Unlock(); }
|
||||||
bool IsLocked() const { return BLocker::IsLocked(); }
|
bool IsLocked() const { return BLocker::IsLocked(); }
|
||||||
|
|
||||||
status_t AddUserFontFromFile(const char* path,
|
status_t AddUserFontFromFile(const char* path, uint16 index, uint16 instance,
|
||||||
uint16& familyID, uint16& styleID);
|
uint16& familyID, uint16& styleID);
|
||||||
status_t AddUserFontFromMemory(const FT_Byte* fontAddress,
|
status_t AddUserFontFromMemory(const FT_Byte* fontAddress, size_t size,
|
||||||
size_t size, uint16& familyID, uint16& styleID);
|
uint16 index, uint16& familyID, uint16& styleID);
|
||||||
status_t RemoveUserFont(uint16 familyID, uint16 styleID);
|
status_t RemoveUserFont(uint16 familyID, uint16 styleID);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
@@ -160,10 +160,10 @@ FontCacheEntry::Init(const ServerFont& font, bool forceVector)
|
|||||||
|
|
||||||
bool success;
|
bool success;
|
||||||
if (font.FontData() != NULL)
|
if (font.FontData() != NULL)
|
||||||
success = fEngine.Init(NULL, 0, font.Size(), charMap,
|
success = fEngine.Init(NULL, font.FaceIndex(), font.Size(), charMap,
|
||||||
renderingType, hinting, (const void*)font.FontData(), font.FontDataSize());
|
renderingType, hinting, (const void*)font.FontData(), font.FontDataSize());
|
||||||
else
|
else
|
||||||
success = fEngine.Init(font.Path(), 0, font.Size(), charMap,
|
success = fEngine.Init(font.Path(), font.FaceIndex(), font.Size(), charMap,
|
||||||
renderingType, hinting);
|
renderingType, hinting);
|
||||||
|
|
||||||
if (!success) {
|
if (!success) {
|
||||||
|
|||||||
@@ -239,8 +239,8 @@ GlobalFontManager::MessageReceived(BMessage* message)
|
|||||||
if (fromDirectory != NULL) {
|
if (fromDirectory != NULL) {
|
||||||
// find style in source and move it to the target
|
// find style in source and move it to the target
|
||||||
nodeRef.node = node;
|
nodeRef.node = node;
|
||||||
FontStyle* style = fromDirectory->FindStyle(nodeRef);
|
FontStyle* style;
|
||||||
if (style != NULL) {
|
while ((style = fromDirectory->FindStyle(nodeRef)) != NULL) {
|
||||||
fromDirectory->styles.RemoveItem(style, false);
|
fromDirectory->styles.RemoveItem(style, false);
|
||||||
directory->styles.AddItem(style);
|
directory->styles.AddItem(style);
|
||||||
style->UpdatePath(directory->directory);
|
style->UpdatePath(directory->directory);
|
||||||
@@ -505,8 +505,8 @@ GlobalFontManager::_RemoveStyle(dev_t device, uint64 directoryNode, uint64 node)
|
|||||||
if (directory != NULL) {
|
if (directory != NULL) {
|
||||||
// find style in directory and remove it
|
// find style in directory and remove it
|
||||||
nodeRef.node = node;
|
nodeRef.node = node;
|
||||||
FontStyle* style = directory->FindStyle(nodeRef);
|
FontStyle* style;
|
||||||
if (style != NULL)
|
while ((style = directory->FindStyle(nodeRef)) != NULL)
|
||||||
_RemoveStyle(*directory, style);
|
_RemoveStyle(*directory, style);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -711,18 +711,39 @@ GlobalFontManager::_AddFont(font_directory& directory, BEntry& entry)
|
|||||||
return status;
|
return status;
|
||||||
|
|
||||||
FT_Face face;
|
FT_Face face;
|
||||||
FT_Error error = FT_New_Face(gFreeTypeLibrary, path.Path(), 0, &face);
|
FT_Error error = FT_New_Face(gFreeTypeLibrary, path.Path(), -1, &face);
|
||||||
|
if (error != 0)
|
||||||
|
return B_ERROR;
|
||||||
|
FT_Long count = face->num_faces;
|
||||||
|
FT_Done_Face(face);
|
||||||
|
|
||||||
|
for (FT_Long i = 0; i < count; i++) {
|
||||||
|
FT_Error error = FT_New_Face(gFreeTypeLibrary, path.Path(), -(i + 1), &face);
|
||||||
|
if (error != 0)
|
||||||
|
return B_ERROR;
|
||||||
|
uint32 variableCount = (face->style_flags & 0x7fff0000) >> 16;
|
||||||
|
FT_Done_Face(face);
|
||||||
|
|
||||||
|
uint32 j = variableCount == 0 ? 0 : 1;
|
||||||
|
do {
|
||||||
|
FT_Long faceIndex = i | (j << 16);
|
||||||
|
error = FT_New_Face(gFreeTypeLibrary, path.Path(), faceIndex, &face);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
uint16 familyID, styleID;
|
uint16 familyID, styleID;
|
||||||
status = FontManager::_AddFont(face, nodeRef, path.Path(), familyID, styleID);
|
status = FontManager::_AddFont(face, nodeRef, path.Path(), familyID, styleID);
|
||||||
if (status == B_NAME_IN_USE)
|
if (status == B_NAME_IN_USE) {
|
||||||
return B_OK;
|
status = B_OK;
|
||||||
|
j++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (status < B_OK)
|
if (status < B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
directory.styles.AddItem(GetStyle(familyID, styleID));
|
directory.styles.AddItem(GetStyle(familyID, styleID));
|
||||||
|
j++;
|
||||||
|
} while (j <= variableCount);
|
||||||
|
}
|
||||||
|
|
||||||
if (directory.AlreadyScanned())
|
if (directory.AlreadyScanned())
|
||||||
directory.revision++;
|
directory.revision++;
|
||||||
|
|||||||
Reference in New Issue
Block a user