BFont: allow loading of user fonts from disk or memory

This patch adds an API call to BFont, called LoadFont, that
takes a string path to a font file. The user fonts are managed
via a new class called AppFontManager that inherits from the base
class FontManagerBase but adds the methods to add and remove user
fonts from disk or memory. There is also a new method called UnloadFont
to remove a user font, but on exit of an app all user fonts should be
automatically cleaned up.

Global/system fonts are managed by the GlobalFontManager, which is
a new class that also inherits from the base class FontManagerBase,
replacing the old "FontManager" class.

A maximum of 128 user fonts may be loaded, and memory fonts
may not exceed 20MB.

There's also an overloaded version of LoadFont that accepts
an area_id and loads the font from memory. A size and offset may
optionally be provided to allow for an area that contains more
than just a font.

Change-Id: I6add42bdf0c0cefc0e2e2a4984fd848c3e7269e5
Reviewed-on: https://review.haiku-os.org/c/haiku/+/4790
Tested-by: Commit checker robot <no-reply+buildbot@haiku-os.org>
Reviewed-by: Adrien Destugues <pulkomandy@pulkomandy.tk>
This commit is contained in:
Dale Cieslak 2022-07-19 22:45:45 -07:00 committed by Adrien Destugues
parent 65f096fd08
commit 85b82f8524
31 changed files with 2077 additions and 1023 deletions

View File

@ -282,6 +282,11 @@ public:
void PrintToStream() const;
status_t LoadFont(const char* path);
status_t LoadFont(const area_id fontAreaID,
uint32 size = 0, uint32 offset = 0);
status_t UnloadFont();
private:
friend void _init_global_fonts_();

View File

@ -146,6 +146,9 @@ enum {
AS_GET_TRUNCATED_STRINGS,
AS_GET_UNICODE_BLOCKS,
AS_GET_HAS_UNICODE_BLOCK,
AS_ADD_FONT_FILE,
AS_ADD_FONT_MEMORY,
AS_REMOVE_FONT,
// Screen methods
AS_VALID_SCREEN_ID,

View File

@ -559,6 +559,7 @@ BFont::SetFamilyAndStyle(const font_family family, const font_style style)
link.Read<uint16>(&fFamilyID);
link.Read<uint16>(&fStyleID);
link.Read<uint16>(&fFace);
fHeight.ascent = kUninitializedAscent;
fExtraFlags = kUninitializedExtraFlags;
@ -943,6 +944,7 @@ BFont::GetTunedInfo(int32 index, tuned_font_info* info) const
}
// Truncates a string to a given _pixel_ width based on the font and size
void
BFont::TruncateString(BString* inOut, uint32 mode, float width) const
{
@ -1452,3 +1454,76 @@ BFont::_GetExtraFlags() const
link.Read<uint32>(&fExtraFlags);
}
status_t
BFont::LoadFont(const char* path)
{
BPrivate::AppServerLink link;
link.StartMessage(AS_ADD_FONT_FILE);
link.AttachString(path);
status_t status = B_ERROR;
if (link.FlushWithReply(status) != B_OK || status != B_OK) {
return status;
}
link.Read<uint16>(&fFamilyID);
link.Read<uint16>(&fStyleID);
link.Read<uint16>(&fFace);
fHeight.ascent = kUninitializedAscent;
fExtraFlags = kUninitializedExtraFlags;
return B_OK;
}
status_t
BFont::LoadFont(const area_id fontAreaID, uint32 size, uint32 offset)
{
BPrivate::AppServerLink link;
link.StartMessage(AS_ADD_FONT_MEMORY);
link.Attach<int32>(fontAreaID);
link.Attach<uint32>(size);
link.Attach<uint32>(offset);
status_t status = B_ERROR;
if (link.FlushWithReply(status) != B_OK || status != B_OK) {
return status;
}
link.Read<uint16>(&fFamilyID);
link.Read<uint16>(&fStyleID);
link.Read<uint16>(&fFace);
fHeight.ascent = kUninitializedAscent;
fExtraFlags = kUninitializedExtraFlags;
return B_OK;
}
status_t
BFont::UnloadFont()
{
BPrivate::AppServerLink link;
link.StartMessage(AS_REMOVE_FONT);
link.Attach<uint16>(fFamilyID);
link.Attach<uint16>(fStyleID);
status_t status = B_ERROR;
if (link.FlushWithReply(status) != B_OK || status != B_OK) {
return status;
}
// reset to plain font
fFamilyID = 0;
fStyleID = 0;
fFace = 0;
fHeight.ascent = kUninitializedAscent;
fExtraFlags = kUninitializedExtraFlags;
return B_OK;
}

View File

@ -20,7 +20,7 @@
#include "BitmapManager.h"
#include "Desktop.h"
#include "FontManager.h"
#include "GlobalFontManager.h"
#include "InputManager.h"
#include "ScreenManager.h"
#include "ServerProtocol.h"
@ -58,7 +58,7 @@ AppServer::AppServer(status_t* status)
gInputManager = new InputManager();
// Create the font server and scan the proper directories.
gFontManager = new FontManager;
gFontManager = new GlobalFontManager;
if (gFontManager->InitCheck() != B_OK)
debugger("font manager could not be initialized!");

View File

@ -46,7 +46,7 @@
#include "DecorManager.h"
#include "DesktopSettingsPrivate.h"
#include "DrawingEngine.h"
#include "FontManager.h"
#include "GlobalFontManager.h"
#include "HWInterface.h"
#include "InputManager.h"
#include "Screen.h"

View File

@ -23,7 +23,9 @@
#include <ServerReadOnlyMemory.h>
#include "Desktop.h"
#include "FontManager.h"
#include "FontCache.h"
#include "FontCacheEntry.h"
#include "GlobalFontManager.h"
#include "GlobalSubpixelSettings.h"
#include "ServerConfig.h"

View File

@ -145,7 +145,8 @@ DrawState::PopState()
uint16
DrawState::ReadFontFromLink(BPrivate::LinkReceiver& link)
DrawState::ReadFontFromLink(BPrivate::LinkReceiver& link,
AppFontManager* fontManager)
{
uint16 mask;
link.Read<uint16>(&mask);
@ -153,7 +154,7 @@ DrawState::ReadFontFromLink(BPrivate::LinkReceiver& link)
if ((mask & B_FONT_FAMILY_AND_STYLE) != 0) {
uint32 fontID;
link.Read<uint32>(&fontID);
fFont.SetFamilyAndStyle(fontID);
fFont.SetFamilyAndStyle(fontID, fontManager);
}
if ((mask & B_FONT_SIZE) != 0) {

View File

@ -22,6 +22,7 @@
#include <Referenceable.h>
#include <View.h>
#include "AppFontManager.h"
#include "ServerFont.h"
#include "PatternHandler.h"
#include "SimpleTransform.h"
@ -48,7 +49,8 @@ public:
DrawState* PreviousState() const
{ return fPreviousState.Get(); }
uint16 ReadFontFromLink(BPrivate::LinkReceiver& link);
uint16 ReadFontFromLink(BPrivate::LinkReceiver& link,
AppFontManager* fontManager = NULL);
// NOTE: ReadFromLink() does not read Font state!!
// It was separate in ServerWindow, and I didn't
// want to change it without knowing implications.

View File

@ -29,6 +29,8 @@ local font_src =
FontFamily.cpp
FontManager.cpp
FontStyle.cpp
GlobalFontManager.cpp
AppFontManager.cpp
;
UseBuildFeatureHeaders freetype ;

View File

@ -15,7 +15,7 @@
#include <stdio.h>
#include "DrawState.h"
#include "FontManager.h"
#include "GlobalFontManager.h"
#include "Layer.h"
#include "ServerApp.h"
#include "ServerBitmap.h"

View File

@ -126,6 +126,9 @@ string_for_message_code(uint32 code)
CODE(AS_GET_TRUNCATED_STRINGS);
CODE(AS_GET_UNICODE_BLOCKS);
CODE(AS_GET_HAS_UNICODE_BLOCK);
CODE(AS_ADD_FONT_FILE);
CODE(AS_ADD_FONT_MEMORY);
CODE(AS_REMOVE_FONT);
// Screen methods
CODE(AS_VALID_SCREEN_ID);

View File

@ -44,6 +44,7 @@
#include <ServerProtocol.h>
#include <WindowPrivate.h>
#include "AppFontManager.h"
#include "AppServer.h"
#include "BitmapManager.h"
#include "CursorManager.h"
@ -52,7 +53,7 @@
#include "DecorManager.h"
#include "DrawingEngine.h"
#include "EventStream.h"
#include "FontManager.h"
#include "GlobalFontManager.h"
#include "HWInterface.h"
#include "InputManager.h"
#include "OffscreenServerWindow.h"
@ -107,7 +108,8 @@ ServerApp::ServerApp(Desktop* desktop, port_id clientReplyPort,
fViewCursor(NULL),
fCursorHideLevel(0),
fIsActive(false),
fMemoryAllocator(new (std::nothrow) ClientMemoryAllocator(this), true)
fMemoryAllocator(new (std::nothrow) ClientMemoryAllocator(this), true),
fAppFontManager(NULL)
{
if (fSignature.IsEmpty())
fSignature = "application/no-signature";
@ -142,6 +144,9 @@ ServerApp::ServerApp(Desktop* desktop, port_id clientReplyPort,
settings.GetDefaultFixedFont(fFixedFont);
desktop->UnlockSingleWindow();
fAppFontManager = new AppFontManager();
fAppFontManager->Run();
STRACE(("ServerApp %s:\n", Signature()));
STRACE(("\tBApp port: %" B_PRId32 "\n", fClientReplyPort));
STRACE(("\tReceiver port: %" B_PRId32 "\n", fMessagePort));
@ -205,6 +210,9 @@ ServerApp::~ServerApp()
fDesktop->GetCursorManager().DeleteCursors(fClientTeam);
fAppFontManager->Lock();
fAppFontManager->Quit();
STRACE(("ServerApp %s::~ServerApp(): Exiting\n", Signature()));
}
@ -1565,6 +1573,214 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
/* font messages */
case AS_ADD_FONT_FILE:
{
FTRACE(("ServerApp %s: Received BFont creation request\n",
Signature()));
// Add a font for an application from a file
// Attached Data:
// 1) char* - path to font on disk
// Returns:
// 1) uint16 - family ID of added font
// 2) uint16 - style ID of added font
// 3) uint16 - face of added font
fAppFontManager->Lock();
if (fAppFontManager->CountFamilies() > MAX_USER_FONTS) {
fLink.StartMessage(B_NOT_ALLOWED);
fAppFontManager->Unlock();
fLink.Flush();
break;
}
uint16 familyID, styleID;
char* fontPath;
link.ReadString(&fontPath);
status_t status = fAppFontManager->AddUserFontFromFile(fontPath,
familyID, styleID);
fAppFontManager->Unlock();
if (status != B_OK) {
fLink.StartMessage(status);
} else {
ServerFont* font = new(std::nothrow) ServerFont();
if (font == NULL) {
fLink.StartMessage(B_NO_MEMORY);
fLink.Flush();
break;
}
status = font->SetFamilyAndStyle(familyID, styleID,
fAppFontManager);
if (status == B_OK) {
fLink.StartMessage(B_OK);
fLink.Attach<uint16>(font->FamilyID());
fLink.Attach<uint16>(font->StyleID());
fLink.Attach<uint16>(font->Face());
} else {
fLink.StartMessage(status);
delete font;
}
}
fLink.Flush();
break;
}
case AS_ADD_FONT_MEMORY:
{
FTRACE(("ServerApp %s: Received BFont memory creation request\n",
Signature()));
// Add a font for an application from a memory area
// Attached Data:
// 1) area_id - id of memory area where font resides
// 2) uint32 - size of memory area for font
// 3) uint32 - offset to start of font memory
// Returns:
// 1) uint16 - family ID of added font
// 2) uint16 - style ID of added font
// 3) uint16 - face of added font
if (fAppFontManager->CountFamilies() > MAX_USER_FONTS) {
fLink.StartMessage(B_NOT_ALLOWED);
fLink.Flush();
break;
}
area_id fontAreaID, fontAreaCloneID;
area_info fontAreaInfo;
char* area_addr;
uint32 size, offset;
link.Read<int32>(&fontAreaID);
link.Read<uint32>(&size);
link.Read<uint32>(&offset);
fontAreaCloneID = clone_area("user font",
(void **)&area_addr,
B_ANY_ADDRESS,
B_READ_AREA,
fontAreaID);
if (fontAreaCloneID < B_OK) {
fLink.StartMessage(fontAreaCloneID);
fLink.Flush();
break;
}
status_t status = get_area_info(fontAreaCloneID, &fontAreaInfo);
if (status != B_OK) {
fLink.StartMessage(status);
fLink.Flush();
delete_area(fontAreaCloneID);
break;
}
uint32 fontMemorySize = fontAreaInfo.size - offset;
if (size == 0)
size = fontMemorySize;
// Check size of font area and reject if it's too large
if (size > MAX_FONT_DATA_SIZE_BYTES
|| size > fontMemorySize) {
fLink.StartMessage(B_BAD_DATA);
fLink.Flush();
delete_area(fontAreaCloneID);
break;
}
FT_Byte* fontData = (FT_Byte*)(malloc (sizeof(FT_Byte) * size));
if (fontData == NULL) {
delete_area(fontAreaCloneID);
fLink.StartMessage(B_BAD_DATA);
fLink.Flush();
break;
}
memcpy(fontData, (FT_Byte*)fontAreaInfo.address + offset, size);
delete_area(fontAreaCloneID);
uint16 familyID, styleID;
fAppFontManager->Lock();
status = fAppFontManager->AddUserFontFromMemory(fontData, size,
familyID, styleID);
if (status != B_OK) {
fLink.StartMessage(status);
free(fontData);
} else {
ServerFont* font = new(std::nothrow) ServerFont();
if (font == NULL) {
free(fontData);
fLink.StartMessage(B_NO_MEMORY);
fLink.Flush();
break;
}
status = font->SetFamilyAndStyle(familyID, styleID,
fAppFontManager);
if (status == B_OK) {
font->SetFontData(fontData, size);
fLink.StartMessage(B_OK);
fLink.Attach<uint16>(font->FamilyID());
fLink.Attach<uint16>(font->StyleID());
fLink.Attach<uint16>(font->Face());
} else {
fLink.StartMessage(status);
free(fontData);
delete font;
}
}
fAppFontManager->Unlock();
fLink.Flush();
break;
}
case AS_REMOVE_FONT:
{
STRACE(("ServerApp %s: Received BFont removal request\n",
Signature()));
// Remove an application-added font
// Attached Data:
// 1) uint16 - familyID of font to remove
// 2) uint16 - styleID of font to remove
uint16 familyID, styleID;
link.Read<uint16>(&familyID);
link.Read<uint16>(&styleID);
status_t status = B_OK;
fAppFontManager->Lock();
FontStyle* style = fAppFontManager->GetStyle(familyID, styleID);
if (style != NULL) {
status = fAppFontManager->RemoveUserFont(familyID, styleID);
} else
status = B_BAD_VALUE;
fAppFontManager->Unlock();
fLink.StartMessage(status);
fLink.Flush();
break;
}
case AS_SET_SYSTEM_FONT:
{
FTRACE(("ServerApp %s: AS_SET_SYSTEM_FONT\n", Signature()));
@ -1708,7 +1924,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
case AS_GET_FONT_LIST_REVISION:
{
STRACE(("ServerApp %s: AS_GET_FONT_LIST_REVISION\n", Signature()));
FTRACE(("ServerApp %s: AS_GET_FONT_LIST_REVISION\n", Signature()));
fLink.StartMessage(B_OK);
fLink.Attach<int32>(
@ -1739,12 +1955,19 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
gFontManager->Lock();
FontFamily* family = gFontManager->FamilyAt(index);
if (family == NULL) {
gFontManager->Unlock();
fAppFontManager->Lock();
family = fAppFontManager->FamilyAt(index);
}
if (family) {
fLink.StartMessage(B_OK);
fLink.AttachString(family->Name());
fLink.Attach<uint32>(family->Flags());
int32 count = family->CountStyles();
fLink.Attach<int32>(count);
for (int32 i = 0; i < count; i++) {
@ -1757,7 +1980,11 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
} else
fLink.StartMessage(B_BAD_VALUE);
gFontManager->Unlock();
if (gFontManager->IsLocked())
gFontManager->Unlock();
if (fAppFontManager->IsLocked())
fAppFontManager->Unlock();
fLink.Flush();
break;
}
@ -1780,7 +2007,13 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
gFontManager->Lock();
FontStyle *fontStyle = gFontManager->GetStyle(familyID, styleID);
FontStyle* fontStyle = gFontManager->GetStyle(familyID, styleID);
if (fontStyle == NULL) {
gFontManager->Unlock();
fAppFontManager->Lock();
fontStyle = fAppFontManager->GetStyle(familyID, styleID);
}
if (fontStyle != NULL) {
fLink.StartMessage(B_OK);
fLink.AttachString(fontStyle->Family()->Name());
@ -1789,7 +2022,10 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
fLink.StartMessage(B_BAD_VALUE);
fLink.Flush();
gFontManager->Unlock();
if (gFontManager->IsLocked())
gFontManager->Unlock();
if (fAppFontManager->IsLocked())
fAppFontManager->Unlock();
break;
}
@ -1822,8 +2058,14 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
// get the font and return IDs and face
gFontManager->Lock();
FontStyle *fontStyle = gFontManager->GetStyle(family, style,
FontStyle* fontStyle = gFontManager->GetStyle(family, style,
familyID, styleID, face);
if (fontStyle == NULL) {
gFontManager->Unlock();
fAppFontManager->Lock();
fontStyle = fAppFontManager->GetStyle(family, style,
familyID, styleID, face);
}
if (fontStyle != NULL) {
fLink.StartMessage(B_OK);
@ -1837,7 +2079,10 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
} else
fLink.StartMessage(B_NAME_NOT_FOUND);
gFontManager->Unlock();
if (gFontManager->IsLocked())
gFontManager->Unlock();
if (fAppFontManager->IsLocked())
fAppFontManager->Unlock();
} else
fLink.StartMessage(B_BAD_VALUE);
@ -1862,14 +2107,24 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
gFontManager->Lock();
FontStyle *fontStyle = gFontManager->GetStyle(familyID, styleID);
if (fontStyle) {
FontStyle* fontStyle = gFontManager->GetStyle(familyID, styleID);
if (fontStyle == NULL) {
gFontManager->Unlock();
fAppFontManager->Lock();
fontStyle = fAppFontManager->GetStyle(familyID, styleID);
}
if (fontStyle != NULL) {
fLink.StartMessage(B_OK);
fLink.Attach<uint16>((uint16)fontStyle->FileFormat());
} else
fLink.StartMessage(B_BAD_VALUE);
gFontManager->Unlock();
if (gFontManager->IsLocked())
gFontManager->Unlock();
if (fAppFontManager->IsLocked())
fAppFontManager->Unlock();
fLink.Flush();
break;
}
@ -1890,12 +2145,12 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
// Returns:
// 1) float - width of the string in pixels (numStrings times)
uint16 family, style;
uint16 familyID, styleID;
float size;
uint8 spacing;
link.Read<uint16>(&family);
link.Read<uint16>(&style);
link.Read<uint16>(&familyID);
link.Read<uint16>(&styleID);
link.Read<float>(&size);
link.Read<uint8>(&spacing);
int32 numStrings;
@ -1923,7 +2178,10 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
ServerFont font;
if (font.SetFamilyAndStyle(family, style) == B_OK && size > 0) {
status_t status = font.SetFamilyAndStyle(familyID, styleID,
fAppFontManager);
if (status == B_OK && size > 0) {
font.SetSize(size);
font.SetSpacing(spacing);
@ -1970,7 +2228,10 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
ServerFont font;
if (font.SetFamilyAndStyle(familyID, styleID) == B_OK && size > 0) {
status_t status = font.SetFamilyAndStyle(familyID, styleID,
fAppFontManager);
if (status == B_OK && size > 0) {
font.SetSize(size);
fLink.StartMessage(B_OK);
@ -1999,14 +2260,24 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
gFontManager->Lock();
FontStyle *fontStyle = gFontManager->GetStyle(familyID, styleID);
FontStyle* fontStyle = gFontManager->GetStyle(familyID, styleID);
if (fontStyle == NULL) {
gFontManager->Unlock();
fAppFontManager->Lock();
fontStyle = fAppFontManager->GetStyle(familyID, styleID);
}
if (fontStyle != NULL) {
fLink.StartMessage(B_OK);
fLink.Attach<int32>(fontStyle->TunedCount());
} else
fLink.StartMessage(B_BAD_VALUE);
gFontManager->Unlock();
if (gFontManager->IsLocked())
gFontManager->Unlock();
if (fAppFontManager->IsLocked())
fAppFontManager->Unlock();
fLink.Flush();
break;
}
@ -2048,14 +2319,24 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
gFontManager->Lock();
FontStyle *fontStyle = gFontManager->GetStyle(familyID, styleID);
FontStyle* fontStyle = gFontManager->GetStyle(familyID, styleID);
if (fontStyle == NULL) {
gFontManager->Unlock();
fAppFontManager->Lock();
fontStyle = fAppFontManager->GetStyle(familyID, styleID);
}
if (fontStyle != NULL) {
fLink.StartMessage(B_OK);
fLink.Attach<uint32>(fontStyle->Flags());
} else
fLink.StartMessage(B_BAD_VALUE);
gFontManager->Unlock();
if (gFontManager->IsLocked())
gFontManager->Unlock();
if (fAppFontManager->IsLocked())
fAppFontManager->Unlock();
fLink.Flush();
break;
}
@ -2077,7 +2358,13 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
gFontManager->Lock();
FontStyle *fontStyle = gFontManager->GetStyle(familyID, styleID);
FontStyle* fontStyle = gFontManager->GetStyle(familyID, styleID);
if (fontStyle == NULL) {
gFontManager->Unlock();
fAppFontManager->Lock();
fontStyle = fAppFontManager->GetStyle(familyID, styleID);
}
if (fontStyle != NULL) {
font_height height;
fontStyle->GetHeight(size, height);
@ -2087,7 +2374,11 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
} else
fLink.StartMessage(B_BAD_VALUE);
gFontManager->Unlock();
if (gFontManager->IsLocked())
gFontManager->Unlock();
if (fAppFontManager->IsLocked())
fAppFontManager->Unlock();
fLink.Flush();
break;
}
@ -2108,7 +2399,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
link.Read<uint16>(&styleID);
ServerFont font;
status_t status = font.SetFamilyAndStyle(familyID, styleID);
status_t status = font.SetFamilyAndStyle(familyID, styleID,
fAppFontManager);
if (status == B_OK) {
unicode_block blocksForFont;
font.GetUnicodeBlocks(blocksForFont);
@ -2143,7 +2436,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
link.Read<uint32>(&end);
ServerFont font;
status_t status = font.SetFamilyAndStyle(familyID, styleID);
status_t status = font.SetFamilyAndStyle(familyID, styleID,
fAppFontManager);
if (status == B_OK) {
bool hasBlock;
@ -2204,7 +2499,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
link.Read(charArray, numBytes);
ServerFont font;
status_t status = font.SetFamilyAndStyle(familyID, styleID);
status_t status = font.SetFamilyAndStyle(familyID, styleID,
fAppFontManager);
if (status == B_OK) {
font.SetSize(size);
font.SetShear(shear);
@ -2259,7 +2556,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
link.Read(charArray, numBytes);
ServerFont font;
status_t status = font.SetFamilyAndStyle(familyID, styleID);
status_t status = font.SetFamilyAndStyle(familyID, styleID,
fAppFontManager);
if (status == B_OK) {
status = font.GetHasGlyphs(charArray, numBytes, numChars,
hasArray);
@ -2308,7 +2607,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
link.Read(charArray, numBytes);
ServerFont font;
status_t status = font.SetFamilyAndStyle(familyID, styleID);
status_t status = font.SetFamilyAndStyle(familyID, styleID,
fAppFontManager);
if (status == B_OK) {
status = font.GetEdges(charArray, numBytes, numChars,
edgeArray);
@ -2386,7 +2687,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
link.Read(charArray, numBytes);
ServerFont font;
status_t status = font.SetFamilyAndStyle(familyID, styleID);
status_t status = font.SetFamilyAndStyle(familyID, styleID,
fAppFontManager);
if (status == B_OK) {
font.SetSize(size);
font.SetSpacing(spacing);
@ -2471,7 +2774,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
// figure out escapements
ServerFont font;
status_t status = font.SetFamilyAndStyle(familyID, styleID);
status_t status = font.SetFamilyAndStyle(familyID, styleID,
fAppFontManager);
if (status == B_OK) {
font.SetSize(size);
font.SetSpacing(spacing);
@ -2558,7 +2863,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
// figure out escapements
ServerFont font;
status_t status = font.SetFamilyAndStyle(familyID, styleID);
status_t status = font.SetFamilyAndStyle(familyID, styleID,
fAppFontManager);
if (status == B_OK) {
font.SetSize(size);
font.SetRotation(rotation);
@ -2646,7 +2953,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
}
ServerFont font;
status_t status = font.SetFamilyAndStyle(familyID, styleID);
status_t status = font.SetFamilyAndStyle(familyID, styleID,
fAppFontManager);
if (status == B_OK) {
font.SetSize(ptsize);
font.SetRotation(rotation);

View File

@ -13,6 +13,7 @@
#define SERVER_APP_H
#include "AppFontManager.h"
#include "ClientMemoryAllocator.h"
#include "MessageLooper.h"
#include "ServerFont.h"
@ -96,6 +97,7 @@ public:
BPrivate::BTokenSpace& ViewTokens() { return fViewTokens; }
void NotifyDeleteClientArea(area_id serverArea);
AppFontManager* FontManager() { return fAppFontManager; }
private:
virtual void _GetLooperName(char* name, size_t size);
@ -160,6 +162,8 @@ private:
bool fIsActive;
BReference<ClientMemoryAllocator> fMemoryAllocator;
AppFontManager* fAppFontManager;
};

View File

@ -13,8 +13,9 @@
#include "ServerFont.h"
#include "Angle.h"
#include "AppFontManager.h"
#include "GlyphLayoutEngine.h"
#include "FontManager.h"
#include "GlobalFontManager.h"
#include "truncate_string.h"
#include "utf8_functions.h"
@ -272,8 +273,10 @@ ServerFont::SetStyle(FontStyle* style)
\return B_OK if successful, B_ERROR if not
*/
status_t
ServerFont::SetFamilyAndStyle(uint16 familyID, uint16 styleID)
ServerFont::SetFamilyAndStyle(uint16 familyID, uint16 styleID,
AppFontManager* fontManager)
{
BReference<FontStyle> style;
if (gFontManager->Lock()) {
@ -282,8 +285,16 @@ ServerFont::SetFamilyAndStyle(uint16 familyID, uint16 styleID)
gFontManager->Unlock();
}
if (style == NULL)
return B_ERROR;
if (style == NULL) {
if (fontManager != NULL && fontManager->Lock()) {
style.SetTo(fontManager->GetStyle(familyID, styleID), false);
fontManager->Unlock();
}
if (style == NULL)
return B_ERROR;
}
SetStyle(style);
@ -300,12 +311,12 @@ ServerFont::SetFamilyAndStyle(uint16 familyID, uint16 styleID)
\return B_OK if successful, B_ERROR if not
*/
status_t
ServerFont::SetFamilyAndStyle(uint32 fontID)
ServerFont::SetFamilyAndStyle(uint32 fontID, AppFontManager* fontManager)
{
uint16 style = fontID & 0xFFFF;
uint16 family = (fontID & 0xFFFF0000) >> 16;
return SetFamilyAndStyle(family, style);
return SetFamilyAndStyle(family, style, fontManager);
}
@ -369,6 +380,9 @@ ServerFont::SetFace(uint16 face)
uint32
ServerFont::GetFamilyAndStyle() const
{
if (fStyle == NULL || fStyle->Family() == NULL)
return 0;
return (FamilyID() << 16) | StyleID();
}
@ -1188,3 +1202,10 @@ ServerFont::EmbeddedTransformation() const
return transform;
}
void
ServerFont::SetFontData(FT_Byte* location, uint32 size)
{
if (fStyle != NULL)
fStyle->SetFontData(location, size);
}

View File

@ -15,7 +15,9 @@
#include <Font.h>
#include <Rect.h>
#include "AppFontManager.h"
#include "FontFamily.h"
#include "FontManager.h"
#include "GlobalSubpixelSettings.h"
#include "Transformable.h"
@ -69,8 +71,10 @@ class ServerFont {
void SetStyle(FontStyle* style);
status_t SetFamilyAndStyle(uint16 familyID,
uint16 styleID);
status_t SetFamilyAndStyle(uint32 fontID);
uint16 styleID,
AppFontManager* fontManager = NULL);
status_t SetFamilyAndStyle(uint32 fontID,
AppFontManager* fontManager = NULL);
uint16 StyleID() const
{ return fStyle->ID(); }
@ -167,8 +171,15 @@ class ServerFont {
status_t IncludesUnicodeBlock(uint32 start, uint32 end,
bool &hasBlock);
void SetFontData(FT_Byte* location, uint32 size);
uint32 FontDataSize() const
{ return fStyle->FontDataSize(); }
FT_Byte* FontData() const
{ return fStyle->FontData(); }
protected:
friend class FontStyle;
FT_Face GetTransformedFace(bool rotate,
bool shear) const;
void PutTransformedFace(FT_Face face) const;

View File

@ -19,7 +19,7 @@
#include "AlphaMask.h"
#include "DrawingEngine.h"
#include "DrawState.h"
#include "FontManager.h"
#include "GlobalFontManager.h"
#include "Layer.h"
#include "ServerApp.h"
#include "ServerBitmap.h"

View File

@ -1299,7 +1299,8 @@ fDesktop->LockSingleWindow();
DTRACE(("ServerWindow %s: Message AS_VIEW_SET_FONT_STATE: "
"View name: %s\n", fTitle, fCurrentView->Name()));
fCurrentView->CurrentState()->ReadFontFromLink(link);
fCurrentView->CurrentState()->ReadFontFromLink(link,
fServerApp->FontManager());
fWindow->GetDrawingEngine()->SetFont(
fCurrentView->CurrentState());
break;

View File

@ -0,0 +1,205 @@
/*
* Copyright 2001-2016, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* DarkWyrm <bpmagic@columbus.rr.com>
* Axel Dörfler, axeld@pinc-software.de
*/
/*! Manages user font families and styles */
#include "AppFontManager.h"
#include <new>
#include <stdint.h>
#include <syslog.h>
#include <Autolock.h>
#include <Debug.h>
#include <Directory.h>
#include <Entry.h>
#include <File.h>
#include <FindDirectory.h>
#include <Message.h>
#include <NodeMonitor.h>
#include <Path.h>
#include <String.h>
#include "FontFamily.h"
#include "FontManager.h"
#include "ServerConfig.h"
#include "ServerFont.h"
#define TRACE_FONT_MANAGER
#ifdef TRACE_FONT_MANAGER
# define FTRACE(x) debug_printf x
#else
# define FTRACE(x) ;
#endif
// #pragma mark -
/*! Sets high id number to avoid collisions with GlobalFontManager
The result of a collision would be that the global font is selected
rather than the application font.
*/
AppFontManager::AppFontManager()
: FontManagerBase(false, "AppFontManager")
{
fNextID = UINT16_MAX;
}
//! Frees all families and styles loaded by the application
AppFontManager::~AppFontManager()
{
while (fFamilies.CountItems() > 0) {
FontFamily* family = fFamilies.ItemAt(0);
while (family->CountStyles() > 0) {
uint16 familyID = family->ID();
uint16 styleID = family->StyleAt(0)->ID();
FontKey fKey(familyID, styleID);
FontStyle* styleRef = fStyleHashTable.Get(fKey);
family->RemoveStyle(styleRef, this);
styleRef->ReleaseReference();
}
fFamilies.RemoveItem(family);
delete family;
}
}
void
AppFontManager::MessageReceived(BMessage* message)
{
FontManagerBase::MessageReceived(message);
}
status_t
AppFontManager::_AddUserFont(FT_Face face, node_ref nodeRef, const char* path,
uint16& familyID, uint16& styleID)
{
FontFamily* family = _FindFamily(face->family_name);
if (family != NULL
&& family->HasStyle(face->style_name)) {
// prevent adding the same style twice
// (this indicates a problem with the installed fonts maybe?)
FT_Done_Face(face);
return B_NAME_IN_USE;
}
if (family == NULL) {
family = new (std::nothrow) FontFamily(face->family_name, fNextID--);
if (family == NULL
|| !fFamilies.BinaryInsert(family, compare_font_families)) {
delete family;
FT_Done_Face(face);
return B_NO_MEMORY;
}
}
FTRACE(("\tadd style: %s, %s\n", face->family_name, face->style_name));
// the FontStyle takes over ownership of the FT_Face object
FontStyle* style = new (std::nothrow) FontStyle(nodeRef, path, face);
if (style == NULL || !family->AddStyle(style, this)) {
delete style;
delete family;
return B_NO_MEMORY;
}
familyID = style->Family()->ID();
styleID = style->ID();
fStyleHashTable.Put(FontKey(familyID, styleID), style);
return B_OK;
}
/*! \brief Adds the FontFamily/FontStyle that is represented by this path.
*/
status_t
AppFontManager::AddUserFontFromFile(const char* path,
uint16& familyID, uint16& styleID)
{
ASSERT(IsLocked());
BEntry entry;
status_t status = entry.SetTo(path);
if (status != B_OK)
return status;
node_ref nodeRef;
status = entry.GetNodeRef(&nodeRef);
if (status < B_OK)
return status;
FT_Face face;
FT_Error error = FT_New_Face(gFreeTypeLibrary, path, 0, &face);
if (error != 0)
return error;
status = _AddUserFont(face, nodeRef, path, familyID, styleID);
return status;
}
/*! \brief Adds the FontFamily/FontStyle that is represented by the area in memory.
*/
status_t
AppFontManager::AddUserFontFromMemory(const FT_Byte* fontAddress, uint32 size,
uint16& familyID, uint16& styleID)
{
ASSERT(IsLocked());
node_ref nodeRef;
status_t status;
FT_Face face;
FT_Error error = FT_New_Memory_Face(gFreeTypeLibrary, fontAddress, size, 0,
&face);
if (error != 0)
return error;
status = _AddUserFont(face, nodeRef, "", familyID, styleID);
return status;
}
/*! \brief Removes the FontFamily/FontStyle from the font manager.
*/
status_t
AppFontManager::RemoveUserFont(uint16 familyID, uint16 styleID)
{
ASSERT(IsLocked());
FontKey fKey(familyID, styleID);
FontStyle* styleRef = fStyleHashTable.Get(fKey);
fStyleHashTable.Remove(fKey);
FontFamily* family = styleRef->Family();
bool removed = family->RemoveStyle(styleRef, this);
if (!removed)
syslog(LOG_DEBUG, "AppFontManager::RemoveUserFont style not removed from family\n");
fFamilies.RemoveItem(family);
delete family;
styleRef->ReleaseReference();
return B_OK;
}

View File

@ -0,0 +1,66 @@
/*
* Copyright 2001-2009, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* DarkWyrm <bpmagic@columbus.rr.com>
* Axel Dörfler, axeld@pinc-software.de
*/
#ifndef APP_FONT_MANAGER_H
#define APP_FONT_MANAGER_H
#include "FontManager.h"
#include <AutoDeleter.h>
#include <HashMap.h>
#include <Looper.h>
#include <ObjectList.h>
#include <Referenceable.h>
#include <ft2build.h>
#include FT_FREETYPE_H
class BEntry;
class BPath;
struct node_ref;
class FontFamily;
class FontStyle;
class ServerFont;
// font areas should be less than 20MB
#define MAX_FONT_DATA_SIZE_BYTES 20 * 1024 * 1024
#define MAX_USER_FONTS 128
/*!
\class AppFontManager AppFontManager.h
\brief Manager for application-added fonts in the font subsystem
*/
class AppFontManager : public FontManagerBase {
public:
AppFontManager();
virtual ~AppFontManager();
virtual void MessageReceived(BMessage* message);
status_t AddUserFontFromFile(const char* path,
uint16& familyID, uint16& styleID);
status_t AddUserFontFromMemory(const FT_Byte* fontAddress,
uint32 size, uint16& familyID, uint16& styleID);
status_t RemoveUserFont(uint16 familyID, uint16 styleID);
private:
status_t _AddUserFont(FT_Face face, node_ref nodeRef,
const char* path,
uint16& familyID, uint16& styleID);
private:
int32 fNextID;
};
#endif /* APP_FONT_MANAGER_H */

View File

@ -158,12 +158,20 @@ FontCacheEntry::Init(const ServerFont& font, bool forceVector)
FT_Encoding charMap = FT_ENCODING_NONE;
bool hinting = font.Hinting();
if (!fEngine.Init(font.Path(), 0, font.Size(), charMap,
renderingType, hinting)) {
bool success;
if (font.FontData() != NULL)
success = fEngine.Init(NULL, 0, font.Size(), charMap,
renderingType, hinting, (const void*)font.FontData(), font.FontDataSize());
else
success = fEngine.Init(font.Path(), 0, font.Size(), charMap,
renderingType, hinting);
if (!success) {
fprintf(stderr, "FontCacheEntry::Init() - some error loading font "
"file %s\n", font.Path());
return false;
}
if (fGlyphCache->Init() != B_OK) {
fprintf(stderr, "FontCacheEntry::Init() - failed to allocate "
"GlyphCache table for font file %s\n", font.Path());

View File

@ -638,7 +638,7 @@ FontEngine::GetKerning(uint32 first, uint32 second, double* x, double* y)
bool
FontEngine::Init(const char* fontFilePath, unsigned faceIndex, double size,
FT_Encoding charMap, glyph_rendering ren_type, bool hinting,
const char* fontFileBuffer, const long fontFileBufferSize)
const void* fontFileBuffer, const long fontFileBufferSize)
{
if (!fLibraryInitialized)
return false;

View File

@ -82,7 +82,7 @@ class FontEngine {
FT_Encoding char_map,
glyph_rendering ren_type,
bool hinting,
const char* fontFileBuffer = NULL,
const void* fontFileBuffer = NULL,
const long fontFileBufferSize = 0);
int LastError() const

View File

@ -12,7 +12,7 @@
#include "FontFamily.h"
#include "FontManager.h"
#include "GlobalFontManager.h"
#include <FontPrivate.h>
@ -78,6 +78,8 @@ FontFamily::~FontFamily()
// we remove us before deleting the style, so that the font manager
// is not contacted to remove the style from us
style->_SetFontFamily(NULL, -1);
style->ReleaseReference();
}
}
@ -98,7 +100,7 @@ FontFamily::Name() const
\param style pointer to FontStyle object to be added
*/
bool
FontFamily::AddStyle(FontStyle *style)
FontFamily::AddStyle(FontStyle* style, AppFontManager* fontManager)
{
if (!style)
return false;
@ -115,6 +117,7 @@ FontFamily::AddStyle(FontStyle *style)
return false;
style->_SetFontFamily(this, fNextID++);
style->_SetFontManager(fontManager);
// force a refresh if a request for font flags is needed
fFlags = kInvalidFamilyFlags;
@ -129,9 +132,9 @@ FontFamily::AddStyle(FontStyle *style)
The font style will not be deleted.
*/
bool
FontFamily::RemoveStyle(FontStyle* style)
FontFamily::RemoveStyle(FontStyle* style, AppFontManager* fontManager)
{
if (!gFontManager->IsLocked()) {
if (!gFontManager->IsLocked() && fontManager == NULL) {
debugger("FontFamily::RemoveStyle() called without having the font manager locked!");
return false;
}

View File

@ -13,6 +13,7 @@
#include <ObjectList.h>
#include <String.h>
#include "AppFontManager.h"
#include "FontStyle.h"
@ -30,8 +31,10 @@ public:
const char* Name() const;
bool AddStyle(FontStyle* style);
bool RemoveStyle(FontStyle* style);
bool AddStyle(FontStyle* style,
AppFontManager* fontManager = NULL);
bool RemoveStyle(FontStyle* style,
AppFontManager* fontManager = NULL);
FontStyle* GetStyle(const char* style) const;
FontStyle* GetStyleMatchingFace(uint16 face) const;

File diff suppressed because it is too large Load Diff

View File

@ -31,89 +31,55 @@ class ServerFont;
/*!
\class FontManager FontManager.h
\brief Manager for the largest part of the font subsystem
\brief Base class interface used by GlobalFontManager and AppFontManager
*/
class FontManager : public BLooper {
class FontManagerBase : public BLooper {
public:
FontManager();
virtual ~FontManager();
FontManagerBase(bool init_freetype,
const char* className = "FontManagerBase");
virtual ~FontManagerBase();
status_t InitCheck() { return fInitStatus; }
void SaveRecentFontMappings();
void SetInitStatus(status_t new_status)
{ fInitStatus = new_status; }
virtual void MessageReceived(BMessage* message);
int32 CheckRevision(uid_t user);
int32 CountFamilies();
virtual int32 CountFamilies();
int32 CountStyles(const char* family);
int32 CountStyles(uint16 familyID);
virtual int32 CountStyles(const char* family);
virtual int32 CountStyles(uint16 familyID);
FontFamily* FamilyAt(int32 index) const;
FontFamily* GetFamily(uint16 familyID) const;
FontFamily* GetFamily(const char* name);
virtual FontFamily* GetFamily(uint16 familyID) const;
virtual 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);
FontStyle* GetStyle(uint16 familyID,
virtual FontStyle* GetStyle(uint16 familyID,
uint16 styleID) const;
virtual FontStyle* GetStyle(const char* familyName,
const char* styleName,
uint16 familyID = 0xffff,
uint16 styleID = 0xffff,
uint16 face = 0);
FontStyle* FindStyleMatchingFace(uint16 face) const;
void RemoveStyle(FontStyle* style);
// This call must not be used by anything else than class
// FontStyle.
const ServerFont* DefaultPlainFont() const;
const ServerFont* DefaultBoldFont() const;
const ServerFont* DefaultFixedFont() const;
void AttachUser(uid_t userID);
void DetachUser(uid_t userID);
private:
struct font_directory;
struct font_mapping;
void _AddDefaultMapping(const char* family,
const char* style, const char* path);
bool _LoadRecentFontMappings();
status_t _AddMappedFont(const char* family,
const char* style = NULL);
FontStyle* _GetDefaultStyle(const char* familyName,
const char* styleName,
const char* fallbackFamily,
const char* fallbackStyle,
uint16 fallbackFace);
status_t _SetDefaultFonts();
void _PrecacheFontFile(const ServerFont* font);
void _AddSystemPaths();
font_directory* _FindDirectory(node_ref& nodeRef);
void _RemoveDirectory(font_directory* directory);
status_t _CreateDirectories(const char* path);
status_t _AddPath(const char* path);
status_t _AddPath(BEntry& entry,
font_directory** _newDirectory = NULL);
void _RemoveStyle(font_directory& directory,
FontStyle* style);
void _RemoveStyle(dev_t device, uint64 directory,
uint64 node);
FontFamily* _FindFamily(const char* family) const;
void _ScanFontsIfNecessary();
void _ScanFonts();
status_t _ScanFontDirectory(font_directory& directory);
status_t _AddFont(font_directory& directory,
BEntry& entry);
FT_CharMap _GetSupportedCharmap(const FT_Face& face);
private:
protected:
FontFamily* _FindFamily(const char* family) const;
static int compare_font_families(const FontFamily* a,
const FontFamily* b);
struct FontKey {
FontKey(uint16 family, uint16 style)
: familyID(family), styleID(style) {}
@ -132,31 +98,17 @@ private:
uint16 familyID, styleID;
};
private:
status_t fInitStatus;
typedef BObjectList<font_directory> DirectoryList;
typedef BObjectList<font_mapping> MappingList;
typedef BObjectList<FontFamily> FamilyList;
DirectoryList fDirectories;
MappingList fMappings;
FamilyList fFamilies;
HashMap<FontKey, BReference<FontStyle> > fStyleHashTable;
ObjectDeleter<ServerFont>
fDefaultPlainFont;
ObjectDeleter<ServerFont>
fDefaultBoldFont;
ObjectDeleter<ServerFont>
fDefaultFixedFont;
bool fScanned;
int32 fNextID;
uint16 fNextID;
bool fHasFreetypeLibrary;
};
extern FT_Library gFreeTypeLibrary;
extern FontManager* gFontManager;
#endif /* FONT_MANAGER_H */

View File

@ -12,7 +12,7 @@
#include "FontFamily.h"
#include "ServerFont.h"
#include "FontManager.h"
#include "GlobalFontManager.h"
#include <FontPrivate.h>
@ -38,7 +38,8 @@ FontStyle::FontStyle(node_ref& nodeRef, const char* path, FT_Face face)
fID(0),
fBounds(0, 0, 0, 0),
fFace(_TranslateStyleToFace(face->style_name)),
fFullAndHalfFixed(false)
fFullAndHalfFixed(false),
fFontData(NULL)
{
fName.Truncate(B_FONT_STYLE_LENGTH);
// make sure this style can be found using the Be API
@ -93,12 +94,20 @@ FontStyle::FontStyle(node_ref& nodeRef, const char* path, FT_Face face)
FontStyle::~FontStyle()
{
// make sure the font server is ours
if (fFamily != NULL && gFontManager->Lock()) {
gFontManager->RemoveStyle(this);
gFontManager->Unlock();
if (fFamily != NULL) {
if (fFontManager != NULL && fFontManager->Lock()) {
fFontManager->RemoveStyle(this);
fFontManager->Unlock();
} else if (gFontManager->Lock()) {
gFontManager->RemoveStyle(this);
gFontManager->Unlock();
}
}
FT_Done_Face(fFreeTypeFace);
if (fFontData != NULL)
free(fFontData);
}
@ -260,3 +269,13 @@ FontStyle::_TranslateStyleToFace(const char* name) const
}
void
FontStyle::SetFontData(FT_Byte* location, uint32 size)
{
// if memory was already allocated here, we should free it so it's not leaked
if (fFontData != NULL)
free(fFontData);
fFontDataSize = size;
fFontData = location;
}

View File

@ -22,8 +22,11 @@
#include <ft2build.h>
#include FT_FREETYPE_H
#include "AppFontManager.h"
struct node_ref;
class AppFontManager;
class FontFamily;
class ServerFont;
@ -131,11 +134,19 @@ class FontStyle : public BReferenceable {
status_t UpdateFace(FT_Face face);
uint32 FontDataSize() const
{ return fFontDataSize; }
void SetFontData(FT_Byte* location, uint32 size);
FT_Byte* FontData() const
{ return fFontData; }
private:
friend class FontFamily;
uint16 _TranslateStyleToFace(const char *name) const;
void _SetFontFamily(FontFamily* family, uint16 id);
void _SetFontManager(AppFontManager* fontManager)
{ fFontManager = fontManager; }
private:
FT_Face fFreeTypeFace;
BString fName;
@ -150,6 +161,10 @@ class FontStyle : public BReferenceable {
font_height fHeight;
uint16 fFace;
bool fFullAndHalfFixed;
FT_Byte* fFontData;
uint32 fFontDataSize;
AppFontManager* fFontManager;
};
#endif // FONT_STYLE_H_

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,130 @@
/*
* Copyright 2001-2009, Haiku.
* Distributed under the terms of the MIT License.
*
* Authors:
* DarkWyrm <bpmagic@columbus.rr.com>
* Axel Dörfler, axeld@pinc-software.de
*/
#ifndef GLOBAL_FONT_MANAGER_H
#define GLOBAL_FONT_MANAGER_H
#include "FontManager.h"
#include <AutoDeleter.h>
#include <HashMap.h>
#include <Looper.h>
#include <ObjectList.h>
#include <Referenceable.h>
#include <ft2build.h>
#include FT_FREETYPE_H
class BEntry;
class BPath;
struct node_ref;
class FontFamily;
class FontStyle;
class ServerFont;
/*!
\class GlobalFontManager GlobalFontManager.h
\brief Manager for system fonts within the font subsystem
*/
class GlobalFontManager : public FontManagerBase {
public:
GlobalFontManager();
virtual ~GlobalFontManager();
void SaveRecentFontMappings();
virtual void MessageReceived(BMessage* message);
virtual int32 CountFamilies();
virtual int32 CountStyles(const char* family);
virtual int32 CountStyles(uint16 familyID);
int32 CheckRevision(uid_t user);
const ServerFont* DefaultPlainFont() const;
const ServerFont* DefaultBoldFont() const;
const ServerFont* DefaultFixedFont() const;
void AttachUser(uid_t userID);
void DetachUser(uid_t userID);
virtual FontFamily* GetFamily(uint16 familyID) const;
virtual FontFamily* GetFamily(const char* name);
virtual FontStyle* GetStyle(uint16 familyID,
uint16 styleID) const;
virtual FontStyle* GetStyle(const char* familyName,
const char* styleName,
uint16 familyID = 0xffff,
uint16 styleID = 0xffff,
uint16 face = 0);
private:
struct font_directory;
struct font_mapping;
void _AddDefaultMapping(const char* family,
const char* style, const char* path);
bool _LoadRecentFontMappings();
status_t _AddMappedFont(const char* family,
const char* style = NULL);
void _PrecacheFontFile(const ServerFont* font);
void _AddSystemPaths();
font_directory* _FindDirectory(node_ref& nodeRef);
void _RemoveDirectory(font_directory* directory);
status_t _CreateDirectories(const char* path);
status_t _AddPath(const char* path);
status_t _AddPath(BEntry& entry,
font_directory** _newDirectory = NULL);
void _ScanFontsIfNecessary();
void _ScanFonts();
status_t _ScanFontDirectory(font_directory& directory);
status_t _AddFont(font_directory& directory,
BEntry& entry);
void _RemoveStyle(font_directory& directory,
FontStyle* style);
void _RemoveStyle(dev_t device, uint64 directory,
uint64 node);
FontStyle* _GetDefaultStyle(const char* familyName,
const char* styleName,
const char* fallbackFamily,
const char* fallbackStyle,
uint16 fallbackFace);
status_t _SetDefaultFonts();
private:
status_t fInitStatus;
typedef BObjectList<font_directory> DirectoryList;
typedef BObjectList<font_mapping> MappingList;
DirectoryList fDirectories;
MappingList fMappings;
ObjectDeleter<ServerFont>
fDefaultPlainFont;
ObjectDeleter<ServerFont>
fDefaultBoldFont;
ObjectDeleter<ServerFont>
fDefaultFixedFont;
bool fScanned;
};
extern GlobalFontManager* gFontManager;
extern FT_Library gFreeTypeLibrary;
#endif /* GLOBAL_FONT_MANAGER_H */

View File

@ -13,7 +13,7 @@
#include "FontCache.h"
#include "FontCacheEntry.h"
#include "FontManager.h"
#include "GlobalFontManager.h"
#include "ServerFont.h"
#include <Autolock.h>