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:
parent
65f096fd08
commit
85b82f8524
@ -282,6 +282,11 @@ public:
|
|||||||
|
|
||||||
void PrintToStream() const;
|
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:
|
private:
|
||||||
friend void _init_global_fonts_();
|
friend void _init_global_fonts_();
|
||||||
|
|
||||||
|
@ -146,6 +146,9 @@ enum {
|
|||||||
AS_GET_TRUNCATED_STRINGS,
|
AS_GET_TRUNCATED_STRINGS,
|
||||||
AS_GET_UNICODE_BLOCKS,
|
AS_GET_UNICODE_BLOCKS,
|
||||||
AS_GET_HAS_UNICODE_BLOCK,
|
AS_GET_HAS_UNICODE_BLOCK,
|
||||||
|
AS_ADD_FONT_FILE,
|
||||||
|
AS_ADD_FONT_MEMORY,
|
||||||
|
AS_REMOVE_FONT,
|
||||||
|
|
||||||
// Screen methods
|
// Screen methods
|
||||||
AS_VALID_SCREEN_ID,
|
AS_VALID_SCREEN_ID,
|
||||||
|
@ -559,6 +559,7 @@ BFont::SetFamilyAndStyle(const font_family family, const font_style style)
|
|||||||
link.Read<uint16>(&fFamilyID);
|
link.Read<uint16>(&fFamilyID);
|
||||||
link.Read<uint16>(&fStyleID);
|
link.Read<uint16>(&fStyleID);
|
||||||
link.Read<uint16>(&fFace);
|
link.Read<uint16>(&fFace);
|
||||||
|
|
||||||
fHeight.ascent = kUninitializedAscent;
|
fHeight.ascent = kUninitializedAscent;
|
||||||
fExtraFlags = kUninitializedExtraFlags;
|
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
|
void
|
||||||
BFont::TruncateString(BString* inOut, uint32 mode, float width) const
|
BFont::TruncateString(BString* inOut, uint32 mode, float width) const
|
||||||
{
|
{
|
||||||
@ -1452,3 +1454,76 @@ BFont::_GetExtraFlags() const
|
|||||||
|
|
||||||
link.Read<uint32>(&fExtraFlags);
|
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;
|
||||||
|
}
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
#include "BitmapManager.h"
|
#include "BitmapManager.h"
|
||||||
#include "Desktop.h"
|
#include "Desktop.h"
|
||||||
#include "FontManager.h"
|
#include "GlobalFontManager.h"
|
||||||
#include "InputManager.h"
|
#include "InputManager.h"
|
||||||
#include "ScreenManager.h"
|
#include "ScreenManager.h"
|
||||||
#include "ServerProtocol.h"
|
#include "ServerProtocol.h"
|
||||||
@ -58,7 +58,7 @@ AppServer::AppServer(status_t* status)
|
|||||||
gInputManager = new InputManager();
|
gInputManager = new InputManager();
|
||||||
|
|
||||||
// Create the font server and scan the proper directories.
|
// Create the font server and scan the proper directories.
|
||||||
gFontManager = new FontManager;
|
gFontManager = new GlobalFontManager;
|
||||||
if (gFontManager->InitCheck() != B_OK)
|
if (gFontManager->InitCheck() != B_OK)
|
||||||
debugger("font manager could not be initialized!");
|
debugger("font manager could not be initialized!");
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@
|
|||||||
#include "DecorManager.h"
|
#include "DecorManager.h"
|
||||||
#include "DesktopSettingsPrivate.h"
|
#include "DesktopSettingsPrivate.h"
|
||||||
#include "DrawingEngine.h"
|
#include "DrawingEngine.h"
|
||||||
#include "FontManager.h"
|
#include "GlobalFontManager.h"
|
||||||
#include "HWInterface.h"
|
#include "HWInterface.h"
|
||||||
#include "InputManager.h"
|
#include "InputManager.h"
|
||||||
#include "Screen.h"
|
#include "Screen.h"
|
||||||
|
@ -23,7 +23,9 @@
|
|||||||
#include <ServerReadOnlyMemory.h>
|
#include <ServerReadOnlyMemory.h>
|
||||||
|
|
||||||
#include "Desktop.h"
|
#include "Desktop.h"
|
||||||
#include "FontManager.h"
|
#include "FontCache.h"
|
||||||
|
#include "FontCacheEntry.h"
|
||||||
|
#include "GlobalFontManager.h"
|
||||||
#include "GlobalSubpixelSettings.h"
|
#include "GlobalSubpixelSettings.h"
|
||||||
#include "ServerConfig.h"
|
#include "ServerConfig.h"
|
||||||
|
|
||||||
|
@ -145,7 +145,8 @@ DrawState::PopState()
|
|||||||
|
|
||||||
|
|
||||||
uint16
|
uint16
|
||||||
DrawState::ReadFontFromLink(BPrivate::LinkReceiver& link)
|
DrawState::ReadFontFromLink(BPrivate::LinkReceiver& link,
|
||||||
|
AppFontManager* fontManager)
|
||||||
{
|
{
|
||||||
uint16 mask;
|
uint16 mask;
|
||||||
link.Read<uint16>(&mask);
|
link.Read<uint16>(&mask);
|
||||||
@ -153,7 +154,7 @@ DrawState::ReadFontFromLink(BPrivate::LinkReceiver& link)
|
|||||||
if ((mask & B_FONT_FAMILY_AND_STYLE) != 0) {
|
if ((mask & B_FONT_FAMILY_AND_STYLE) != 0) {
|
||||||
uint32 fontID;
|
uint32 fontID;
|
||||||
link.Read<uint32>(&fontID);
|
link.Read<uint32>(&fontID);
|
||||||
fFont.SetFamilyAndStyle(fontID);
|
fFont.SetFamilyAndStyle(fontID, fontManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mask & B_FONT_SIZE) != 0) {
|
if ((mask & B_FONT_SIZE) != 0) {
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <Referenceable.h>
|
#include <Referenceable.h>
|
||||||
#include <View.h>
|
#include <View.h>
|
||||||
|
|
||||||
|
#include "AppFontManager.h"
|
||||||
#include "ServerFont.h"
|
#include "ServerFont.h"
|
||||||
#include "PatternHandler.h"
|
#include "PatternHandler.h"
|
||||||
#include "SimpleTransform.h"
|
#include "SimpleTransform.h"
|
||||||
@ -48,7 +49,8 @@ public:
|
|||||||
DrawState* PreviousState() const
|
DrawState* PreviousState() const
|
||||||
{ return fPreviousState.Get(); }
|
{ return fPreviousState.Get(); }
|
||||||
|
|
||||||
uint16 ReadFontFromLink(BPrivate::LinkReceiver& link);
|
uint16 ReadFontFromLink(BPrivate::LinkReceiver& link,
|
||||||
|
AppFontManager* fontManager = NULL);
|
||||||
// NOTE: ReadFromLink() does not read Font state!!
|
// NOTE: ReadFromLink() does not read Font state!!
|
||||||
// It was separate in ServerWindow, and I didn't
|
// It was separate in ServerWindow, and I didn't
|
||||||
// want to change it without knowing implications.
|
// want to change it without knowing implications.
|
||||||
|
@ -29,6 +29,8 @@ local font_src =
|
|||||||
FontFamily.cpp
|
FontFamily.cpp
|
||||||
FontManager.cpp
|
FontManager.cpp
|
||||||
FontStyle.cpp
|
FontStyle.cpp
|
||||||
|
GlobalFontManager.cpp
|
||||||
|
AppFontManager.cpp
|
||||||
;
|
;
|
||||||
|
|
||||||
UseBuildFeatureHeaders freetype ;
|
UseBuildFeatureHeaders freetype ;
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "DrawState.h"
|
#include "DrawState.h"
|
||||||
#include "FontManager.h"
|
#include "GlobalFontManager.h"
|
||||||
#include "Layer.h"
|
#include "Layer.h"
|
||||||
#include "ServerApp.h"
|
#include "ServerApp.h"
|
||||||
#include "ServerBitmap.h"
|
#include "ServerBitmap.h"
|
||||||
|
@ -126,6 +126,9 @@ string_for_message_code(uint32 code)
|
|||||||
CODE(AS_GET_TRUNCATED_STRINGS);
|
CODE(AS_GET_TRUNCATED_STRINGS);
|
||||||
CODE(AS_GET_UNICODE_BLOCKS);
|
CODE(AS_GET_UNICODE_BLOCKS);
|
||||||
CODE(AS_GET_HAS_UNICODE_BLOCK);
|
CODE(AS_GET_HAS_UNICODE_BLOCK);
|
||||||
|
CODE(AS_ADD_FONT_FILE);
|
||||||
|
CODE(AS_ADD_FONT_MEMORY);
|
||||||
|
CODE(AS_REMOVE_FONT);
|
||||||
|
|
||||||
// Screen methods
|
// Screen methods
|
||||||
CODE(AS_VALID_SCREEN_ID);
|
CODE(AS_VALID_SCREEN_ID);
|
||||||
|
@ -44,6 +44,7 @@
|
|||||||
#include <ServerProtocol.h>
|
#include <ServerProtocol.h>
|
||||||
#include <WindowPrivate.h>
|
#include <WindowPrivate.h>
|
||||||
|
|
||||||
|
#include "AppFontManager.h"
|
||||||
#include "AppServer.h"
|
#include "AppServer.h"
|
||||||
#include "BitmapManager.h"
|
#include "BitmapManager.h"
|
||||||
#include "CursorManager.h"
|
#include "CursorManager.h"
|
||||||
@ -52,7 +53,7 @@
|
|||||||
#include "DecorManager.h"
|
#include "DecorManager.h"
|
||||||
#include "DrawingEngine.h"
|
#include "DrawingEngine.h"
|
||||||
#include "EventStream.h"
|
#include "EventStream.h"
|
||||||
#include "FontManager.h"
|
#include "GlobalFontManager.h"
|
||||||
#include "HWInterface.h"
|
#include "HWInterface.h"
|
||||||
#include "InputManager.h"
|
#include "InputManager.h"
|
||||||
#include "OffscreenServerWindow.h"
|
#include "OffscreenServerWindow.h"
|
||||||
@ -107,7 +108,8 @@ ServerApp::ServerApp(Desktop* desktop, port_id clientReplyPort,
|
|||||||
fViewCursor(NULL),
|
fViewCursor(NULL),
|
||||||
fCursorHideLevel(0),
|
fCursorHideLevel(0),
|
||||||
fIsActive(false),
|
fIsActive(false),
|
||||||
fMemoryAllocator(new (std::nothrow) ClientMemoryAllocator(this), true)
|
fMemoryAllocator(new (std::nothrow) ClientMemoryAllocator(this), true),
|
||||||
|
fAppFontManager(NULL)
|
||||||
{
|
{
|
||||||
if (fSignature.IsEmpty())
|
if (fSignature.IsEmpty())
|
||||||
fSignature = "application/no-signature";
|
fSignature = "application/no-signature";
|
||||||
@ -142,6 +144,9 @@ ServerApp::ServerApp(Desktop* desktop, port_id clientReplyPort,
|
|||||||
settings.GetDefaultFixedFont(fFixedFont);
|
settings.GetDefaultFixedFont(fFixedFont);
|
||||||
desktop->UnlockSingleWindow();
|
desktop->UnlockSingleWindow();
|
||||||
|
|
||||||
|
fAppFontManager = new AppFontManager();
|
||||||
|
fAppFontManager->Run();
|
||||||
|
|
||||||
STRACE(("ServerApp %s:\n", Signature()));
|
STRACE(("ServerApp %s:\n", Signature()));
|
||||||
STRACE(("\tBApp port: %" B_PRId32 "\n", fClientReplyPort));
|
STRACE(("\tBApp port: %" B_PRId32 "\n", fClientReplyPort));
|
||||||
STRACE(("\tReceiver port: %" B_PRId32 "\n", fMessagePort));
|
STRACE(("\tReceiver port: %" B_PRId32 "\n", fMessagePort));
|
||||||
@ -205,6 +210,9 @@ ServerApp::~ServerApp()
|
|||||||
|
|
||||||
fDesktop->GetCursorManager().DeleteCursors(fClientTeam);
|
fDesktop->GetCursorManager().DeleteCursors(fClientTeam);
|
||||||
|
|
||||||
|
fAppFontManager->Lock();
|
||||||
|
fAppFontManager->Quit();
|
||||||
|
|
||||||
STRACE(("ServerApp %s::~ServerApp(): Exiting\n", Signature()));
|
STRACE(("ServerApp %s::~ServerApp(): Exiting\n", Signature()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1565,6 +1573,214 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
|
|
||||||
/* font messages */
|
/* 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:
|
case AS_SET_SYSTEM_FONT:
|
||||||
{
|
{
|
||||||
FTRACE(("ServerApp %s: AS_SET_SYSTEM_FONT\n", Signature()));
|
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:
|
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.StartMessage(B_OK);
|
||||||
fLink.Attach<int32>(
|
fLink.Attach<int32>(
|
||||||
@ -1739,12 +1955,19 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
gFontManager->Lock();
|
gFontManager->Lock();
|
||||||
|
|
||||||
FontFamily* family = gFontManager->FamilyAt(index);
|
FontFamily* family = gFontManager->FamilyAt(index);
|
||||||
|
if (family == NULL) {
|
||||||
|
gFontManager->Unlock();
|
||||||
|
fAppFontManager->Lock();
|
||||||
|
family = fAppFontManager->FamilyAt(index);
|
||||||
|
}
|
||||||
|
|
||||||
if (family) {
|
if (family) {
|
||||||
fLink.StartMessage(B_OK);
|
fLink.StartMessage(B_OK);
|
||||||
fLink.AttachString(family->Name());
|
fLink.AttachString(family->Name());
|
||||||
fLink.Attach<uint32>(family->Flags());
|
fLink.Attach<uint32>(family->Flags());
|
||||||
|
|
||||||
int32 count = family->CountStyles();
|
int32 count = family->CountStyles();
|
||||||
|
|
||||||
fLink.Attach<int32>(count);
|
fLink.Attach<int32>(count);
|
||||||
|
|
||||||
for (int32 i = 0; i < count; i++) {
|
for (int32 i = 0; i < count; i++) {
|
||||||
@ -1757,7 +1980,11 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
} else
|
} else
|
||||||
fLink.StartMessage(B_BAD_VALUE);
|
fLink.StartMessage(B_BAD_VALUE);
|
||||||
|
|
||||||
gFontManager->Unlock();
|
if (gFontManager->IsLocked())
|
||||||
|
gFontManager->Unlock();
|
||||||
|
if (fAppFontManager->IsLocked())
|
||||||
|
fAppFontManager->Unlock();
|
||||||
|
|
||||||
fLink.Flush();
|
fLink.Flush();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1780,7 +2007,13 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
|
|
||||||
gFontManager->Lock();
|
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) {
|
if (fontStyle != NULL) {
|
||||||
fLink.StartMessage(B_OK);
|
fLink.StartMessage(B_OK);
|
||||||
fLink.AttachString(fontStyle->Family()->Name());
|
fLink.AttachString(fontStyle->Family()->Name());
|
||||||
@ -1789,7 +2022,10 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
fLink.StartMessage(B_BAD_VALUE);
|
fLink.StartMessage(B_BAD_VALUE);
|
||||||
|
|
||||||
fLink.Flush();
|
fLink.Flush();
|
||||||
gFontManager->Unlock();
|
if (gFontManager->IsLocked())
|
||||||
|
gFontManager->Unlock();
|
||||||
|
if (fAppFontManager->IsLocked())
|
||||||
|
fAppFontManager->Unlock();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1822,8 +2058,14 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
// get the font and return IDs and face
|
// get the font and return IDs and face
|
||||||
gFontManager->Lock();
|
gFontManager->Lock();
|
||||||
|
|
||||||
FontStyle *fontStyle = gFontManager->GetStyle(family, style,
|
FontStyle* fontStyle = gFontManager->GetStyle(family, style,
|
||||||
familyID, styleID, face);
|
familyID, styleID, face);
|
||||||
|
if (fontStyle == NULL) {
|
||||||
|
gFontManager->Unlock();
|
||||||
|
fAppFontManager->Lock();
|
||||||
|
fontStyle = fAppFontManager->GetStyle(family, style,
|
||||||
|
familyID, styleID, face);
|
||||||
|
}
|
||||||
|
|
||||||
if (fontStyle != NULL) {
|
if (fontStyle != NULL) {
|
||||||
fLink.StartMessage(B_OK);
|
fLink.StartMessage(B_OK);
|
||||||
@ -1837,7 +2079,10 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
} else
|
} else
|
||||||
fLink.StartMessage(B_NAME_NOT_FOUND);
|
fLink.StartMessage(B_NAME_NOT_FOUND);
|
||||||
|
|
||||||
gFontManager->Unlock();
|
if (gFontManager->IsLocked())
|
||||||
|
gFontManager->Unlock();
|
||||||
|
if (fAppFontManager->IsLocked())
|
||||||
|
fAppFontManager->Unlock();
|
||||||
} else
|
} else
|
||||||
fLink.StartMessage(B_BAD_VALUE);
|
fLink.StartMessage(B_BAD_VALUE);
|
||||||
|
|
||||||
@ -1862,14 +2107,24 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
|
|
||||||
gFontManager->Lock();
|
gFontManager->Lock();
|
||||||
|
|
||||||
FontStyle *fontStyle = gFontManager->GetStyle(familyID, styleID);
|
FontStyle* fontStyle = gFontManager->GetStyle(familyID, styleID);
|
||||||
if (fontStyle) {
|
if (fontStyle == NULL) {
|
||||||
|
gFontManager->Unlock();
|
||||||
|
fAppFontManager->Lock();
|
||||||
|
fontStyle = fAppFontManager->GetStyle(familyID, styleID);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fontStyle != NULL) {
|
||||||
fLink.StartMessage(B_OK);
|
fLink.StartMessage(B_OK);
|
||||||
fLink.Attach<uint16>((uint16)fontStyle->FileFormat());
|
fLink.Attach<uint16>((uint16)fontStyle->FileFormat());
|
||||||
} else
|
} else
|
||||||
fLink.StartMessage(B_BAD_VALUE);
|
fLink.StartMessage(B_BAD_VALUE);
|
||||||
|
|
||||||
gFontManager->Unlock();
|
if (gFontManager->IsLocked())
|
||||||
|
gFontManager->Unlock();
|
||||||
|
if (fAppFontManager->IsLocked())
|
||||||
|
fAppFontManager->Unlock();
|
||||||
|
|
||||||
fLink.Flush();
|
fLink.Flush();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1890,12 +2145,12 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
// 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 familyID, styleID;
|
||||||
float size;
|
float size;
|
||||||
uint8 spacing;
|
uint8 spacing;
|
||||||
|
|
||||||
link.Read<uint16>(&family);
|
link.Read<uint16>(&familyID);
|
||||||
link.Read<uint16>(&style);
|
link.Read<uint16>(&styleID);
|
||||||
link.Read<float>(&size);
|
link.Read<float>(&size);
|
||||||
link.Read<uint8>(&spacing);
|
link.Read<uint8>(&spacing);
|
||||||
int32 numStrings;
|
int32 numStrings;
|
||||||
@ -1923,7 +2178,10 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
|
|
||||||
ServerFont font;
|
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.SetSize(size);
|
||||||
font.SetSpacing(spacing);
|
font.SetSpacing(spacing);
|
||||||
|
|
||||||
@ -1970,7 +2228,10 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
|
|
||||||
ServerFont font;
|
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);
|
font.SetSize(size);
|
||||||
|
|
||||||
fLink.StartMessage(B_OK);
|
fLink.StartMessage(B_OK);
|
||||||
@ -1999,14 +2260,24 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
|
|
||||||
gFontManager->Lock();
|
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) {
|
if (fontStyle != NULL) {
|
||||||
fLink.StartMessage(B_OK);
|
fLink.StartMessage(B_OK);
|
||||||
fLink.Attach<int32>(fontStyle->TunedCount());
|
fLink.Attach<int32>(fontStyle->TunedCount());
|
||||||
} else
|
} else
|
||||||
fLink.StartMessage(B_BAD_VALUE);
|
fLink.StartMessage(B_BAD_VALUE);
|
||||||
|
|
||||||
gFontManager->Unlock();
|
if (gFontManager->IsLocked())
|
||||||
|
gFontManager->Unlock();
|
||||||
|
if (fAppFontManager->IsLocked())
|
||||||
|
fAppFontManager->Unlock();
|
||||||
|
|
||||||
fLink.Flush();
|
fLink.Flush();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2048,14 +2319,24 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
|
|
||||||
gFontManager->Lock();
|
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) {
|
if (fontStyle != NULL) {
|
||||||
fLink.StartMessage(B_OK);
|
fLink.StartMessage(B_OK);
|
||||||
fLink.Attach<uint32>(fontStyle->Flags());
|
fLink.Attach<uint32>(fontStyle->Flags());
|
||||||
} else
|
} else
|
||||||
fLink.StartMessage(B_BAD_VALUE);
|
fLink.StartMessage(B_BAD_VALUE);
|
||||||
|
|
||||||
gFontManager->Unlock();
|
if (gFontManager->IsLocked())
|
||||||
|
gFontManager->Unlock();
|
||||||
|
if (fAppFontManager->IsLocked())
|
||||||
|
fAppFontManager->Unlock();
|
||||||
|
|
||||||
fLink.Flush();
|
fLink.Flush();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2077,7 +2358,13 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
|
|
||||||
gFontManager->Lock();
|
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) {
|
if (fontStyle != NULL) {
|
||||||
font_height height;
|
font_height height;
|
||||||
fontStyle->GetHeight(size, height);
|
fontStyle->GetHeight(size, height);
|
||||||
@ -2087,7 +2374,11 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
} else
|
} else
|
||||||
fLink.StartMessage(B_BAD_VALUE);
|
fLink.StartMessage(B_BAD_VALUE);
|
||||||
|
|
||||||
gFontManager->Unlock();
|
if (gFontManager->IsLocked())
|
||||||
|
gFontManager->Unlock();
|
||||||
|
if (fAppFontManager->IsLocked())
|
||||||
|
fAppFontManager->Unlock();
|
||||||
|
|
||||||
fLink.Flush();
|
fLink.Flush();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -2108,7 +2399,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
link.Read<uint16>(&styleID);
|
link.Read<uint16>(&styleID);
|
||||||
|
|
||||||
ServerFont font;
|
ServerFont font;
|
||||||
status_t status = font.SetFamilyAndStyle(familyID, styleID);
|
status_t status = font.SetFamilyAndStyle(familyID, styleID,
|
||||||
|
fAppFontManager);
|
||||||
|
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
unicode_block blocksForFont;
|
unicode_block blocksForFont;
|
||||||
font.GetUnicodeBlocks(blocksForFont);
|
font.GetUnicodeBlocks(blocksForFont);
|
||||||
@ -2143,7 +2436,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
link.Read<uint32>(&end);
|
link.Read<uint32>(&end);
|
||||||
|
|
||||||
ServerFont font;
|
ServerFont font;
|
||||||
status_t status = font.SetFamilyAndStyle(familyID, styleID);
|
status_t status = font.SetFamilyAndStyle(familyID, styleID,
|
||||||
|
fAppFontManager);
|
||||||
|
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
bool hasBlock;
|
bool hasBlock;
|
||||||
|
|
||||||
@ -2204,7 +2499,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
link.Read(charArray, numBytes);
|
link.Read(charArray, numBytes);
|
||||||
|
|
||||||
ServerFont font;
|
ServerFont font;
|
||||||
status_t status = font.SetFamilyAndStyle(familyID, styleID);
|
status_t status = font.SetFamilyAndStyle(familyID, styleID,
|
||||||
|
fAppFontManager);
|
||||||
|
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
font.SetSize(size);
|
font.SetSize(size);
|
||||||
font.SetShear(shear);
|
font.SetShear(shear);
|
||||||
@ -2259,7 +2556,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
link.Read(charArray, numBytes);
|
link.Read(charArray, numBytes);
|
||||||
|
|
||||||
ServerFont font;
|
ServerFont font;
|
||||||
status_t status = font.SetFamilyAndStyle(familyID, styleID);
|
status_t status = font.SetFamilyAndStyle(familyID, styleID,
|
||||||
|
fAppFontManager);
|
||||||
|
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
status = font.GetHasGlyphs(charArray, numBytes, numChars,
|
status = font.GetHasGlyphs(charArray, numBytes, numChars,
|
||||||
hasArray);
|
hasArray);
|
||||||
@ -2308,7 +2607,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
link.Read(charArray, numBytes);
|
link.Read(charArray, numBytes);
|
||||||
|
|
||||||
ServerFont font;
|
ServerFont font;
|
||||||
status_t status = font.SetFamilyAndStyle(familyID, styleID);
|
status_t status = font.SetFamilyAndStyle(familyID, styleID,
|
||||||
|
fAppFontManager);
|
||||||
|
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
status = font.GetEdges(charArray, numBytes, numChars,
|
status = font.GetEdges(charArray, numBytes, numChars,
|
||||||
edgeArray);
|
edgeArray);
|
||||||
@ -2386,7 +2687,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
link.Read(charArray, numBytes);
|
link.Read(charArray, numBytes);
|
||||||
|
|
||||||
ServerFont font;
|
ServerFont font;
|
||||||
status_t status = font.SetFamilyAndStyle(familyID, styleID);
|
status_t status = font.SetFamilyAndStyle(familyID, styleID,
|
||||||
|
fAppFontManager);
|
||||||
|
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
font.SetSize(size);
|
font.SetSize(size);
|
||||||
font.SetSpacing(spacing);
|
font.SetSpacing(spacing);
|
||||||
@ -2471,7 +2774,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
// figure out escapements
|
// figure out escapements
|
||||||
|
|
||||||
ServerFont font;
|
ServerFont font;
|
||||||
status_t status = font.SetFamilyAndStyle(familyID, styleID);
|
status_t status = font.SetFamilyAndStyle(familyID, styleID,
|
||||||
|
fAppFontManager);
|
||||||
|
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
font.SetSize(size);
|
font.SetSize(size);
|
||||||
font.SetSpacing(spacing);
|
font.SetSpacing(spacing);
|
||||||
@ -2558,7 +2863,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
// figure out escapements
|
// figure out escapements
|
||||||
|
|
||||||
ServerFont font;
|
ServerFont font;
|
||||||
status_t status = font.SetFamilyAndStyle(familyID, styleID);
|
status_t status = font.SetFamilyAndStyle(familyID, styleID,
|
||||||
|
fAppFontManager);
|
||||||
|
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
font.SetSize(size);
|
font.SetSize(size);
|
||||||
font.SetRotation(rotation);
|
font.SetRotation(rotation);
|
||||||
@ -2646,7 +2953,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ServerFont font;
|
ServerFont font;
|
||||||
status_t status = font.SetFamilyAndStyle(familyID, styleID);
|
status_t status = font.SetFamilyAndStyle(familyID, styleID,
|
||||||
|
fAppFontManager);
|
||||||
|
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
font.SetSize(ptsize);
|
font.SetSize(ptsize);
|
||||||
font.SetRotation(rotation);
|
font.SetRotation(rotation);
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#define SERVER_APP_H
|
#define SERVER_APP_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "AppFontManager.h"
|
||||||
#include "ClientMemoryAllocator.h"
|
#include "ClientMemoryAllocator.h"
|
||||||
#include "MessageLooper.h"
|
#include "MessageLooper.h"
|
||||||
#include "ServerFont.h"
|
#include "ServerFont.h"
|
||||||
@ -96,6 +97,7 @@ public:
|
|||||||
BPrivate::BTokenSpace& ViewTokens() { return fViewTokens; }
|
BPrivate::BTokenSpace& ViewTokens() { return fViewTokens; }
|
||||||
|
|
||||||
void NotifyDeleteClientArea(area_id serverArea);
|
void NotifyDeleteClientArea(area_id serverArea);
|
||||||
|
AppFontManager* FontManager() { return fAppFontManager; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual void _GetLooperName(char* name, size_t size);
|
virtual void _GetLooperName(char* name, size_t size);
|
||||||
@ -160,6 +162,8 @@ private:
|
|||||||
bool fIsActive;
|
bool fIsActive;
|
||||||
|
|
||||||
BReference<ClientMemoryAllocator> fMemoryAllocator;
|
BReference<ClientMemoryAllocator> fMemoryAllocator;
|
||||||
|
|
||||||
|
AppFontManager* fAppFontManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -13,8 +13,9 @@
|
|||||||
#include "ServerFont.h"
|
#include "ServerFont.h"
|
||||||
|
|
||||||
#include "Angle.h"
|
#include "Angle.h"
|
||||||
|
#include "AppFontManager.h"
|
||||||
#include "GlyphLayoutEngine.h"
|
#include "GlyphLayoutEngine.h"
|
||||||
#include "FontManager.h"
|
#include "GlobalFontManager.h"
|
||||||
#include "truncate_string.h"
|
#include "truncate_string.h"
|
||||||
#include "utf8_functions.h"
|
#include "utf8_functions.h"
|
||||||
|
|
||||||
@ -272,8 +273,10 @@ ServerFont::SetStyle(FontStyle* style)
|
|||||||
\return B_OK if successful, B_ERROR if not
|
\return B_OK if successful, B_ERROR if not
|
||||||
*/
|
*/
|
||||||
status_t
|
status_t
|
||||||
ServerFont::SetFamilyAndStyle(uint16 familyID, uint16 styleID)
|
ServerFont::SetFamilyAndStyle(uint16 familyID, uint16 styleID,
|
||||||
|
AppFontManager* fontManager)
|
||||||
{
|
{
|
||||||
|
|
||||||
BReference<FontStyle> style;
|
BReference<FontStyle> style;
|
||||||
|
|
||||||
if (gFontManager->Lock()) {
|
if (gFontManager->Lock()) {
|
||||||
@ -282,8 +285,16 @@ ServerFont::SetFamilyAndStyle(uint16 familyID, uint16 styleID)
|
|||||||
gFontManager->Unlock();
|
gFontManager->Unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (style == NULL)
|
if (style == NULL) {
|
||||||
return B_ERROR;
|
if (fontManager != NULL && fontManager->Lock()) {
|
||||||
|
style.SetTo(fontManager->GetStyle(familyID, styleID), false);
|
||||||
|
|
||||||
|
fontManager->Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (style == NULL)
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
SetStyle(style);
|
SetStyle(style);
|
||||||
|
|
||||||
@ -300,12 +311,12 @@ ServerFont::SetFamilyAndStyle(uint16 familyID, uint16 styleID)
|
|||||||
\return B_OK if successful, B_ERROR if not
|
\return B_OK if successful, B_ERROR if not
|
||||||
*/
|
*/
|
||||||
status_t
|
status_t
|
||||||
ServerFont::SetFamilyAndStyle(uint32 fontID)
|
ServerFont::SetFamilyAndStyle(uint32 fontID, AppFontManager* fontManager)
|
||||||
{
|
{
|
||||||
uint16 style = fontID & 0xFFFF;
|
uint16 style = fontID & 0xFFFF;
|
||||||
uint16 family = (fontID & 0xFFFF0000) >> 16;
|
uint16 family = (fontID & 0xFFFF0000) >> 16;
|
||||||
|
|
||||||
return SetFamilyAndStyle(family, style);
|
return SetFamilyAndStyle(family, style, fontManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -369,6 +380,9 @@ ServerFont::SetFace(uint16 face)
|
|||||||
uint32
|
uint32
|
||||||
ServerFont::GetFamilyAndStyle() const
|
ServerFont::GetFamilyAndStyle() const
|
||||||
{
|
{
|
||||||
|
if (fStyle == NULL || fStyle->Family() == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
return (FamilyID() << 16) | StyleID();
|
return (FamilyID() << 16) | StyleID();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1188,3 +1202,10 @@ ServerFont::EmbeddedTransformation() const
|
|||||||
return transform;
|
return transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ServerFont::SetFontData(FT_Byte* location, uint32 size)
|
||||||
|
{
|
||||||
|
if (fStyle != NULL)
|
||||||
|
fStyle->SetFontData(location, size);
|
||||||
|
}
|
||||||
|
@ -15,7 +15,9 @@
|
|||||||
#include <Font.h>
|
#include <Font.h>
|
||||||
#include <Rect.h>
|
#include <Rect.h>
|
||||||
|
|
||||||
|
#include "AppFontManager.h"
|
||||||
#include "FontFamily.h"
|
#include "FontFamily.h"
|
||||||
|
#include "FontManager.h"
|
||||||
#include "GlobalSubpixelSettings.h"
|
#include "GlobalSubpixelSettings.h"
|
||||||
#include "Transformable.h"
|
#include "Transformable.h"
|
||||||
|
|
||||||
@ -69,8 +71,10 @@ class ServerFont {
|
|||||||
|
|
||||||
void SetStyle(FontStyle* style);
|
void SetStyle(FontStyle* style);
|
||||||
status_t SetFamilyAndStyle(uint16 familyID,
|
status_t SetFamilyAndStyle(uint16 familyID,
|
||||||
uint16 styleID);
|
uint16 styleID,
|
||||||
status_t SetFamilyAndStyle(uint32 fontID);
|
AppFontManager* fontManager = NULL);
|
||||||
|
status_t SetFamilyAndStyle(uint32 fontID,
|
||||||
|
AppFontManager* fontManager = NULL);
|
||||||
|
|
||||||
uint16 StyleID() const
|
uint16 StyleID() const
|
||||||
{ return fStyle->ID(); }
|
{ return fStyle->ID(); }
|
||||||
@ -167,8 +171,15 @@ class ServerFont {
|
|||||||
status_t IncludesUnicodeBlock(uint32 start, uint32 end,
|
status_t IncludesUnicodeBlock(uint32 start, uint32 end,
|
||||||
bool &hasBlock);
|
bool &hasBlock);
|
||||||
|
|
||||||
|
void SetFontData(FT_Byte* location, uint32 size);
|
||||||
|
uint32 FontDataSize() const
|
||||||
|
{ return fStyle->FontDataSize(); }
|
||||||
|
FT_Byte* FontData() const
|
||||||
|
{ return fStyle->FontData(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class FontStyle;
|
friend class FontStyle;
|
||||||
|
|
||||||
FT_Face GetTransformedFace(bool rotate,
|
FT_Face GetTransformedFace(bool rotate,
|
||||||
bool shear) const;
|
bool shear) const;
|
||||||
void PutTransformedFace(FT_Face face) const;
|
void PutTransformedFace(FT_Face face) const;
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
#include "AlphaMask.h"
|
#include "AlphaMask.h"
|
||||||
#include "DrawingEngine.h"
|
#include "DrawingEngine.h"
|
||||||
#include "DrawState.h"
|
#include "DrawState.h"
|
||||||
#include "FontManager.h"
|
#include "GlobalFontManager.h"
|
||||||
#include "Layer.h"
|
#include "Layer.h"
|
||||||
#include "ServerApp.h"
|
#include "ServerApp.h"
|
||||||
#include "ServerBitmap.h"
|
#include "ServerBitmap.h"
|
||||||
|
@ -1299,7 +1299,8 @@ fDesktop->LockSingleWindow();
|
|||||||
DTRACE(("ServerWindow %s: Message AS_VIEW_SET_FONT_STATE: "
|
DTRACE(("ServerWindow %s: Message AS_VIEW_SET_FONT_STATE: "
|
||||||
"View name: %s\n", fTitle, fCurrentView->Name()));
|
"View name: %s\n", fTitle, fCurrentView->Name()));
|
||||||
|
|
||||||
fCurrentView->CurrentState()->ReadFontFromLink(link);
|
fCurrentView->CurrentState()->ReadFontFromLink(link,
|
||||||
|
fServerApp->FontManager());
|
||||||
fWindow->GetDrawingEngine()->SetFont(
|
fWindow->GetDrawingEngine()->SetFont(
|
||||||
fCurrentView->CurrentState());
|
fCurrentView->CurrentState());
|
||||||
break;
|
break;
|
||||||
|
205
src/servers/app/font/AppFontManager.cpp
Normal file
205
src/servers/app/font/AppFontManager.cpp
Normal 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;
|
||||||
|
}
|
66
src/servers/app/font/AppFontManager.h
Normal file
66
src/servers/app/font/AppFontManager.h
Normal 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 */
|
@ -158,12 +158,20 @@ FontCacheEntry::Init(const ServerFont& font, bool forceVector)
|
|||||||
FT_Encoding charMap = FT_ENCODING_NONE;
|
FT_Encoding charMap = FT_ENCODING_NONE;
|
||||||
bool hinting = font.Hinting();
|
bool hinting = font.Hinting();
|
||||||
|
|
||||||
if (!fEngine.Init(font.Path(), 0, font.Size(), charMap,
|
bool success;
|
||||||
renderingType, hinting)) {
|
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 "
|
fprintf(stderr, "FontCacheEntry::Init() - some error loading font "
|
||||||
"file %s\n", font.Path());
|
"file %s\n", font.Path());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fGlyphCache->Init() != B_OK) {
|
if (fGlyphCache->Init() != B_OK) {
|
||||||
fprintf(stderr, "FontCacheEntry::Init() - failed to allocate "
|
fprintf(stderr, "FontCacheEntry::Init() - failed to allocate "
|
||||||
"GlyphCache table for font file %s\n", font.Path());
|
"GlyphCache table for font file %s\n", font.Path());
|
||||||
|
@ -638,7 +638,7 @@ FontEngine::GetKerning(uint32 first, uint32 second, double* x, double* y)
|
|||||||
bool
|
bool
|
||||||
FontEngine::Init(const char* fontFilePath, unsigned faceIndex, double size,
|
FontEngine::Init(const char* fontFilePath, unsigned faceIndex, double size,
|
||||||
FT_Encoding charMap, glyph_rendering ren_type, bool hinting,
|
FT_Encoding charMap, glyph_rendering ren_type, bool hinting,
|
||||||
const char* fontFileBuffer, const long fontFileBufferSize)
|
const void* fontFileBuffer, const long fontFileBufferSize)
|
||||||
{
|
{
|
||||||
if (!fLibraryInitialized)
|
if (!fLibraryInitialized)
|
||||||
return false;
|
return false;
|
||||||
|
@ -82,7 +82,7 @@ class FontEngine {
|
|||||||
FT_Encoding char_map,
|
FT_Encoding char_map,
|
||||||
glyph_rendering ren_type,
|
glyph_rendering ren_type,
|
||||||
bool hinting,
|
bool hinting,
|
||||||
const char* fontFileBuffer = NULL,
|
const void* fontFileBuffer = NULL,
|
||||||
const long fontFileBufferSize = 0);
|
const long fontFileBufferSize = 0);
|
||||||
|
|
||||||
int LastError() const
|
int LastError() const
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
#include "FontFamily.h"
|
#include "FontFamily.h"
|
||||||
|
|
||||||
#include "FontManager.h"
|
#include "GlobalFontManager.h"
|
||||||
|
|
||||||
#include <FontPrivate.h>
|
#include <FontPrivate.h>
|
||||||
|
|
||||||
@ -78,6 +78,8 @@ FontFamily::~FontFamily()
|
|||||||
// we remove us before deleting the style, so that the font manager
|
// we remove us before deleting the style, so that the font manager
|
||||||
// is not contacted to remove the style from us
|
// is not contacted to remove the style from us
|
||||||
style->_SetFontFamily(NULL, -1);
|
style->_SetFontFamily(NULL, -1);
|
||||||
|
|
||||||
|
style->ReleaseReference();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +100,7 @@ FontFamily::Name() const
|
|||||||
\param style pointer to FontStyle object to be added
|
\param style pointer to FontStyle object to be added
|
||||||
*/
|
*/
|
||||||
bool
|
bool
|
||||||
FontFamily::AddStyle(FontStyle *style)
|
FontFamily::AddStyle(FontStyle* style, AppFontManager* fontManager)
|
||||||
{
|
{
|
||||||
if (!style)
|
if (!style)
|
||||||
return false;
|
return false;
|
||||||
@ -115,6 +117,7 @@ FontFamily::AddStyle(FontStyle *style)
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
style->_SetFontFamily(this, fNextID++);
|
style->_SetFontFamily(this, fNextID++);
|
||||||
|
style->_SetFontManager(fontManager);
|
||||||
|
|
||||||
// force a refresh if a request for font flags is needed
|
// force a refresh if a request for font flags is needed
|
||||||
fFlags = kInvalidFamilyFlags;
|
fFlags = kInvalidFamilyFlags;
|
||||||
@ -129,9 +132,9 @@ FontFamily::AddStyle(FontStyle *style)
|
|||||||
The font style will not be deleted.
|
The font style will not be deleted.
|
||||||
*/
|
*/
|
||||||
bool
|
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!");
|
debugger("FontFamily::RemoveStyle() called without having the font manager locked!");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include <ObjectList.h>
|
#include <ObjectList.h>
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
|
|
||||||
|
#include "AppFontManager.h"
|
||||||
#include "FontStyle.h"
|
#include "FontStyle.h"
|
||||||
|
|
||||||
|
|
||||||
@ -30,8 +31,10 @@ public:
|
|||||||
|
|
||||||
const char* Name() const;
|
const char* Name() const;
|
||||||
|
|
||||||
bool AddStyle(FontStyle* style);
|
bool AddStyle(FontStyle* style,
|
||||||
bool RemoveStyle(FontStyle* style);
|
AppFontManager* fontManager = NULL);
|
||||||
|
bool RemoveStyle(FontStyle* style,
|
||||||
|
AppFontManager* fontManager = NULL);
|
||||||
|
|
||||||
FontStyle* GetStyle(const char* style) const;
|
FontStyle* GetStyle(const char* style) const;
|
||||||
FontStyle* GetStyleMatchingFace(uint16 face) const;
|
FontStyle* GetStyleMatchingFace(uint16 face) const;
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -31,89 +31,55 @@ class ServerFont;
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
\class FontManager FontManager.h
|
\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:
|
public:
|
||||||
FontManager();
|
FontManagerBase(bool init_freetype,
|
||||||
virtual ~FontManager();
|
const char* className = "FontManagerBase");
|
||||||
|
virtual ~FontManagerBase();
|
||||||
|
|
||||||
status_t InitCheck() { return fInitStatus; }
|
status_t InitCheck() { return fInitStatus; }
|
||||||
void SaveRecentFontMappings();
|
void SetInitStatus(status_t new_status)
|
||||||
|
{ fInitStatus = new_status; }
|
||||||
|
|
||||||
virtual void MessageReceived(BMessage* message);
|
virtual void MessageReceived(BMessage* message);
|
||||||
|
|
||||||
int32 CheckRevision(uid_t user);
|
virtual int32 CountFamilies();
|
||||||
int32 CountFamilies();
|
|
||||||
|
|
||||||
int32 CountStyles(const char* family);
|
virtual int32 CountStyles(const char* family);
|
||||||
int32 CountStyles(uint16 familyID);
|
virtual int32 CountStyles(uint16 familyID);
|
||||||
FontFamily* FamilyAt(int32 index) const;
|
FontFamily* FamilyAt(int32 index) const;
|
||||||
|
|
||||||
FontFamily* GetFamily(uint16 familyID) const;
|
virtual FontFamily* GetFamily(uint16 familyID) const;
|
||||||
FontFamily* GetFamily(const char* name);
|
virtual FontFamily* GetFamily(const char* name);
|
||||||
|
|
||||||
FontStyle* GetStyleByIndex(const char* family,
|
FontStyle* GetStyleByIndex(const char* family,
|
||||||
int32 index);
|
int32 index);
|
||||||
FontStyle* GetStyleByIndex(uint16 familyID, int32 index);
|
FontStyle* GetStyleByIndex(uint16 familyID, int32 index);
|
||||||
FontStyle* GetStyle(const char* family, const char* style,
|
|
||||||
uint16 familyID = 0xffff,
|
virtual FontStyle* GetStyle(uint16 familyID,
|
||||||
uint16 styleID = 0xffff, uint16 face = 0);
|
|
||||||
FontStyle* GetStyle(const char *family, uint16 styleID);
|
|
||||||
FontStyle* GetStyle(uint16 familyID,
|
|
||||||
uint16 styleID) const;
|
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;
|
FontStyle* FindStyleMatchingFace(uint16 face) const;
|
||||||
|
|
||||||
void RemoveStyle(FontStyle* style);
|
void RemoveStyle(FontStyle* style);
|
||||||
// This call must not be used by anything else than class
|
// This call must not be used by anything else than class
|
||||||
// FontStyle.
|
// 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);
|
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 {
|
struct FontKey {
|
||||||
FontKey(uint16 family, uint16 style)
|
FontKey(uint16 family, uint16 style)
|
||||||
: familyID(family), styleID(style) {}
|
: familyID(family), styleID(style) {}
|
||||||
@ -132,31 +98,17 @@ private:
|
|||||||
uint16 familyID, styleID;
|
uint16 familyID, styleID;
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
|
||||||
status_t fInitStatus;
|
status_t fInitStatus;
|
||||||
|
|
||||||
typedef BObjectList<font_directory> DirectoryList;
|
|
||||||
typedef BObjectList<font_mapping> MappingList;
|
|
||||||
typedef BObjectList<FontFamily> FamilyList;
|
typedef BObjectList<FontFamily> FamilyList;
|
||||||
|
|
||||||
DirectoryList fDirectories;
|
|
||||||
MappingList fMappings;
|
|
||||||
FamilyList fFamilies;
|
FamilyList fFamilies;
|
||||||
|
|
||||||
HashMap<FontKey, BReference<FontStyle> > fStyleHashTable;
|
HashMap<FontKey, BReference<FontStyle> > fStyleHashTable;
|
||||||
|
|
||||||
ObjectDeleter<ServerFont>
|
uint16 fNextID;
|
||||||
fDefaultPlainFont;
|
bool fHasFreetypeLibrary;
|
||||||
ObjectDeleter<ServerFont>
|
|
||||||
fDefaultBoldFont;
|
|
||||||
ObjectDeleter<ServerFont>
|
|
||||||
fDefaultFixedFont;
|
|
||||||
|
|
||||||
bool fScanned;
|
|
||||||
int32 fNextID;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern FT_Library gFreeTypeLibrary;
|
extern FT_Library gFreeTypeLibrary;
|
||||||
extern FontManager* gFontManager;
|
|
||||||
|
|
||||||
#endif /* FONT_MANAGER_H */
|
#endif /* FONT_MANAGER_H */
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
#include "FontFamily.h"
|
#include "FontFamily.h"
|
||||||
#include "ServerFont.h"
|
#include "ServerFont.h"
|
||||||
#include "FontManager.h"
|
#include "GlobalFontManager.h"
|
||||||
|
|
||||||
#include <FontPrivate.h>
|
#include <FontPrivate.h>
|
||||||
|
|
||||||
@ -38,7 +38,8 @@ FontStyle::FontStyle(node_ref& nodeRef, const char* path, FT_Face face)
|
|||||||
fID(0),
|
fID(0),
|
||||||
fBounds(0, 0, 0, 0),
|
fBounds(0, 0, 0, 0),
|
||||||
fFace(_TranslateStyleToFace(face->style_name)),
|
fFace(_TranslateStyleToFace(face->style_name)),
|
||||||
fFullAndHalfFixed(false)
|
fFullAndHalfFixed(false),
|
||||||
|
fFontData(NULL)
|
||||||
{
|
{
|
||||||
fName.Truncate(B_FONT_STYLE_LENGTH);
|
fName.Truncate(B_FONT_STYLE_LENGTH);
|
||||||
// make sure this style can be found using the Be API
|
// 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()
|
FontStyle::~FontStyle()
|
||||||
{
|
{
|
||||||
// make sure the font server is ours
|
// make sure the font server is ours
|
||||||
if (fFamily != NULL && gFontManager->Lock()) {
|
if (fFamily != NULL) {
|
||||||
gFontManager->RemoveStyle(this);
|
if (fFontManager != NULL && fFontManager->Lock()) {
|
||||||
gFontManager->Unlock();
|
fFontManager->RemoveStyle(this);
|
||||||
|
fFontManager->Unlock();
|
||||||
|
} else if (gFontManager->Lock()) {
|
||||||
|
gFontManager->RemoveStyle(this);
|
||||||
|
gFontManager->Unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
FT_Done_Face(fFreeTypeFace);
|
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;
|
||||||
|
}
|
@ -22,8 +22,11 @@
|
|||||||
#include <ft2build.h>
|
#include <ft2build.h>
|
||||||
#include FT_FREETYPE_H
|
#include FT_FREETYPE_H
|
||||||
|
|
||||||
|
#include "AppFontManager.h"
|
||||||
|
|
||||||
|
|
||||||
struct node_ref;
|
struct node_ref;
|
||||||
|
class AppFontManager;
|
||||||
class FontFamily;
|
class FontFamily;
|
||||||
class ServerFont;
|
class ServerFont;
|
||||||
|
|
||||||
@ -131,11 +134,19 @@ class FontStyle : public BReferenceable {
|
|||||||
|
|
||||||
status_t UpdateFace(FT_Face face);
|
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:
|
private:
|
||||||
friend class FontFamily;
|
friend class FontFamily;
|
||||||
uint16 _TranslateStyleToFace(const char *name) const;
|
uint16 _TranslateStyleToFace(const char *name) const;
|
||||||
void _SetFontFamily(FontFamily* family, uint16 id);
|
void _SetFontFamily(FontFamily* family, uint16 id);
|
||||||
|
void _SetFontManager(AppFontManager* fontManager)
|
||||||
|
{ fFontManager = fontManager; }
|
||||||
private:
|
private:
|
||||||
FT_Face fFreeTypeFace;
|
FT_Face fFreeTypeFace;
|
||||||
BString fName;
|
BString fName;
|
||||||
@ -150,6 +161,10 @@ class FontStyle : public BReferenceable {
|
|||||||
font_height fHeight;
|
font_height fHeight;
|
||||||
uint16 fFace;
|
uint16 fFace;
|
||||||
bool fFullAndHalfFixed;
|
bool fFullAndHalfFixed;
|
||||||
|
|
||||||
|
FT_Byte* fFontData;
|
||||||
|
uint32 fFontDataSize;
|
||||||
|
AppFontManager* fFontManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // FONT_STYLE_H_
|
#endif // FONT_STYLE_H_
|
||||||
|
1039
src/servers/app/font/GlobalFontManager.cpp
Normal file
1039
src/servers/app/font/GlobalFontManager.cpp
Normal file
File diff suppressed because it is too large
Load Diff
130
src/servers/app/font/GlobalFontManager.h
Normal file
130
src/servers/app/font/GlobalFontManager.h
Normal 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 */
|
@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
#include "FontCache.h"
|
#include "FontCache.h"
|
||||||
#include "FontCacheEntry.h"
|
#include "FontCacheEntry.h"
|
||||||
#include "FontManager.h"
|
#include "GlobalFontManager.h"
|
||||||
#include "ServerFont.h"
|
#include "ServerFont.h"
|
||||||
|
|
||||||
#include <Autolock.h>
|
#include <Autolock.h>
|
||||||
|
Loading…
Reference in New Issue
Block a user