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 <jerome.duval@gmail.com> Reviewed-by: Máximo Castañeda <antiswen@yahoo.es> Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
This commit is contained in:
parent
fe8f7e314e
commit
d0f06357f5
@ -283,8 +283,11 @@ public:
|
||||
void PrintToStream() const;
|
||||
|
||||
status_t LoadFont(const char* path);
|
||||
status_t LoadFont(const char* path, uint16 index, uint16 instance);
|
||||
status_t LoadFont(const area_id fontAreaID,
|
||||
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();
|
||||
|
||||
private:
|
||||
|
@ -1458,10 +1458,19 @@ BFont::_GetExtraFlags() const
|
||||
|
||||
status_t
|
||||
BFont::LoadFont(const char* path)
|
||||
{
|
||||
return LoadFont(path, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BFont::LoadFont(const char* path, uint16 index, uint16 instance)
|
||||
{
|
||||
BPrivate::AppServerLink link;
|
||||
link.StartMessage(AS_ADD_FONT_FILE);
|
||||
link.AttachString(path);
|
||||
link.Attach<uint16>(index);
|
||||
link.Attach<uint16>(instance);
|
||||
status_t status = B_ERROR;
|
||||
if (link.FlushWithReply(status) != B_OK || status != B_OK) {
|
||||
return status;
|
||||
@ -1479,6 +1488,13 @@ BFont::LoadFont(const char* path)
|
||||
|
||||
status_t
|
||||
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;
|
||||
|
||||
@ -1487,6 +1503,7 @@ BFont::LoadFont(const area_id fontAreaID, size_t size, size_t offset)
|
||||
link.Attach<int32>(fontAreaID);
|
||||
link.Attach<size_t>(size);
|
||||
link.Attach<size_t>(offset);
|
||||
link.Attach<uint16>(index);
|
||||
|
||||
status_t status = B_ERROR;
|
||||
if (link.FlushWithReply(status) != B_OK || status != B_OK) {
|
||||
|
@ -1581,6 +1581,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
|
||||
// Attached Data:
|
||||
// 1) char* - path to font on disk
|
||||
// 2) uint16 - index in font file
|
||||
// 3) uint16 - instance
|
||||
|
||||
// Returns:
|
||||
// 1) uint16 - family ID of added font
|
||||
@ -1597,9 +1599,12 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
|
||||
uint16 familyID, styleID;
|
||||
char* fontPath;
|
||||
uint16 index, instance;
|
||||
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);
|
||||
|
||||
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
|
||||
// 2) size_t - size of memory area for font
|
||||
// 3) size_t - offset to start of font memory
|
||||
// 4) uint16 - index in font buffer
|
||||
|
||||
// Returns:
|
||||
// 1) uint16 - family ID of added font
|
||||
@ -1650,10 +1656,12 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
area_info fontAreaInfo;
|
||||
char* area_addr;
|
||||
size_t size, offset;
|
||||
uint16 index;
|
||||
|
||||
link.Read<int32>(&fontAreaID);
|
||||
link.Read<size_t>(&size);
|
||||
link.Read<size_t>(&offset);
|
||||
link.Read<uint16>(&index);
|
||||
fontAreaCloneID = clone_area("user font",
|
||||
(void **)&area_addr,
|
||||
B_ANY_ADDRESS,
|
||||
@ -1702,7 +1710,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
|
||||
uint16 familyID, styleID;
|
||||
|
||||
status = fAppFontManager->AddUserFontFromMemory(fontData, size,
|
||||
status = fAppFontManager->AddUserFontFromMemory(fontData, size, index,
|
||||
familyID, styleID);
|
||||
|
||||
if (status != B_OK) {
|
||||
|
@ -68,6 +68,8 @@ class ServerFont {
|
||||
const char* Family() const;
|
||||
const char* Path() const
|
||||
{ return fStyle->Path(); }
|
||||
long FaceIndex() const
|
||||
{ return fStyle->FreeTypeFace()->face_index; }
|
||||
|
||||
void SetStyle(FontStyle* style);
|
||||
status_t SetFamilyAndStyle(uint16 familyID,
|
||||
|
@ -50,7 +50,7 @@ AppFontManager::AppFontManager()
|
||||
/*! \brief Adds the FontFamily/FontStyle that is represented by this path.
|
||||
*/
|
||||
status_t
|
||||
AppFontManager::AddUserFontFromFile(const char* path,
|
||||
AppFontManager::AddUserFontFromFile(const char* path, uint16 index, uint16 instance,
|
||||
uint16& familyID, uint16& styleID)
|
||||
{
|
||||
ASSERT(IsLocked());
|
||||
@ -66,12 +66,11 @@ AppFontManager::AddUserFontFromFile(const char* path,
|
||||
return status;
|
||||
|
||||
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)
|
||||
return B_ERROR;
|
||||
|
||||
status = _AddFont(face, nodeRef, path, familyID, styleID);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@ -79,7 +78,7 @@ AppFontManager::AddUserFontFromFile(const char* path,
|
||||
/*! \brief Adds the FontFamily/FontStyle that is represented by the area in memory.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
ASSERT(IsLocked());
|
||||
@ -88,7 +87,7 @@ AppFontManager::AddUserFontFromMemory(const FT_Byte* fontAddress, size_t size,
|
||||
status_t status;
|
||||
|
||||
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);
|
||||
if (error != 0)
|
||||
return B_ERROR;
|
||||
|
@ -37,10 +37,10 @@ public:
|
||||
void Unlock() { BLocker::Unlock(); }
|
||||
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);
|
||||
status_t AddUserFontFromMemory(const FT_Byte* fontAddress,
|
||||
size_t size, uint16& familyID, uint16& styleID);
|
||||
status_t AddUserFontFromMemory(const FT_Byte* fontAddress, size_t size,
|
||||
uint16 index, uint16& familyID, uint16& styleID);
|
||||
status_t RemoveUserFont(uint16 familyID, uint16 styleID);
|
||||
|
||||
private:
|
||||
|
@ -160,10 +160,10 @@ FontCacheEntry::Init(const ServerFont& font, bool forceVector)
|
||||
|
||||
bool success;
|
||||
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());
|
||||
else
|
||||
success = fEngine.Init(font.Path(), 0, font.Size(), charMap,
|
||||
success = fEngine.Init(font.Path(), font.FaceIndex(), font.Size(), charMap,
|
||||
renderingType, hinting);
|
||||
|
||||
if (!success) {
|
||||
|
@ -239,8 +239,8 @@ GlobalFontManager::MessageReceived(BMessage* message)
|
||||
if (fromDirectory != NULL) {
|
||||
// find style in source and move it to the target
|
||||
nodeRef.node = node;
|
||||
FontStyle* style = fromDirectory->FindStyle(nodeRef);
|
||||
if (style != NULL) {
|
||||
FontStyle* style;
|
||||
while ((style = fromDirectory->FindStyle(nodeRef)) != NULL) {
|
||||
fromDirectory->styles.RemoveItem(style, false);
|
||||
directory->styles.AddItem(style);
|
||||
style->UpdatePath(directory->directory);
|
||||
@ -505,8 +505,8 @@ GlobalFontManager::_RemoveStyle(dev_t device, uint64 directoryNode, uint64 node)
|
||||
if (directory != NULL) {
|
||||
// find style in directory and remove it
|
||||
nodeRef.node = node;
|
||||
FontStyle* style = directory->FindStyle(nodeRef);
|
||||
if (style != NULL)
|
||||
FontStyle* style;
|
||||
while ((style = directory->FindStyle(nodeRef)) != NULL)
|
||||
_RemoveStyle(*directory, style);
|
||||
}
|
||||
}
|
||||
@ -711,18 +711,39 @@ GlobalFontManager::_AddFont(font_directory& directory, BEntry& entry)
|
||||
return status;
|
||||
|
||||
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);
|
||||
|
||||
uint16 familyID, styleID;
|
||||
status = FontManager::_AddFont(face, nodeRef, path.Path(), familyID, styleID);
|
||||
if (status == B_NAME_IN_USE)
|
||||
return B_OK;
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
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);
|
||||
|
||||
directory.styles.AddItem(GetStyle(familyID, styleID));
|
||||
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)
|
||||
return B_ERROR;
|
||||
|
||||
uint16 familyID, styleID;
|
||||
status = FontManager::_AddFont(face, nodeRef, path.Path(), familyID, styleID);
|
||||
if (status == B_NAME_IN_USE) {
|
||||
status = B_OK;
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
directory.styles.AddItem(GetStyle(familyID, styleID));
|
||||
j++;
|
||||
} while (j <= variableCount);
|
||||
}
|
||||
|
||||
if (directory.AlreadyScanned())
|
||||
directory.revision++;
|
||||
|
Loading…
Reference in New Issue
Block a user