reorganise Platform.c a bit and remove some unused bits from freetype

This commit is contained in:
UnknownShadow200 2019-02-21 19:45:08 +11:00
parent 31e84040e3
commit 34fca6746f
6 changed files with 203 additions and 585 deletions

View File

@ -1292,9 +1292,7 @@ static void Font_Init(void) {
err = FT_New_Library(&ft_mem, &ft_lib);
if (err) Logger_Abort2(err, "Failed to init freetype");
FT_Add_Default_Modules(ft_lib);
FT_Set_Default_Properties(ft_lib);
if (!File_Exists(&cachePath)) {
Window_ShowDialog("One time load", "Initialising font cache, this can take several seconds.");
@ -1778,6 +1776,200 @@ ReturnCode Audio_StopAndFree(AudioHandle handle) {
}
/*########################################################################################################################*
*-----------------------------------------------------Process/Module------------------------------------------------------*
*#########################################################################################################################*/
#ifdef CC_BUILD_WIN
ReturnCode Platform_GetExePath(String* path) {
TCHAR chars[FILENAME_SIZE + 1];
DWORD len = GetModuleFileName(NULL, chars, FILENAME_SIZE);
if (!len) return GetLastError();
#ifdef UNICODE
Convert_DecodeUtf16(path, chars, len * 2);
#else
Convert_DecodeAscii(path, chars, len);
#endif
return 0;
}
ReturnCode Platform_StartProcess(const String* path, const String* args) {
String file, argv; char argvBuffer[300];
TCHAR str[300], raw[300];
STARTUPINFO si = { 0 };
PROCESS_INFORMATION pi = { 0 };
BOOL ok;
file = *path; Utils_UNSAFE_GetFilename(&file);
String_InitArray(argv, argvBuffer);
String_Format2(&argv, "\"%s\" %s", &file, args);
Platform_ConvertString(str, path);
Platform_ConvertString(raw, &argv);
si.cb = sizeof(STARTUPINFO);
ok = CreateProcess(str, raw, NULL, NULL, false, 0, NULL, NULL, &si, &pi);
if (!ok) return GetLastError();
/* Don't leak memory for proess return code */
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return 0;
}
ReturnCode Platform_StartOpen(const String* args) {
TCHAR str[300];
HINSTANCE instance;
Platform_ConvertString(str, args);
instance = ShellExecute(NULL, NULL, str, NULL, NULL, SW_SHOWNORMAL);
return instance > 32 ? 0 : (ReturnCode)instance;
}
/* Don't need special execute permission on windows */
ReturnCode Platform_MarkExecutable(const String* path) { return 0; }
ReturnCode Platform_LoadLibrary(const String* path, void** lib) {
TCHAR str[300];
Platform_ConvertString(str, path);
*lib = LoadLibrary(str);
return *lib ? 0 : GetLastError();
}
ReturnCode Platform_GetSymbol(void* lib, const char* name, void** symbol) {
*symbol = GetProcAddress(lib, name);
return *symbol ? 0 : GetLastError();
}
#endif
#ifdef CC_BUILD_POSIX
ReturnCode Platform_StartProcess(const String* path, const String* args) {
char str[600], raw[600];
pid_t pid;
int i, j;
Platform_ConvertString(str, path);
Platform_ConvertString(raw, args);
pid = fork();
if (pid == -1) return errno;
if (pid == 0) {
/* Executed in child process */
char* argv[15];
argv[0] = str; argv[1] = raw;
/* need to null-terminate multiple arguments */
for (i = 0, j = 2; raw[i] && i < Array_Elems(raw); i++) {
if (raw[i] != ' ') continue;
/* null terminate previous argument */
raw[i] = '\0';
argv[j++] = &raw[i + 1];
}
argv[j] = NULL;
execvp(str, argv);
_exit(127); /* "command not found" */
} else {
/* Executed in parent process */
/* We do nothing here.. */
return 0;
}
}
ReturnCode Platform_MarkExecutable(const String* path) {
char str[600];
struct stat st;
Platform_ConvertString(str, path);
if (stat(str, &st) == -1) return errno;
st.st_mode |= S_IXUSR;
return chmod(str, st.st_mode) == -1 ? errno : 0;
}
ReturnCode Platform_LoadLibrary(const String* path, void** lib) {
char str[600];
Platform_ConvertString(str, path);
*lib = dlopen(str, RTLD_NOW);
return *lib == NULL;
}
ReturnCode Platform_GetSymbol(void* lib, const char* name, void** symbol) {
*symbol = dlsym(lib, name);
return *symbol == NULL; /* dlerror would be proper, but eh */
}
#endif
#if defined CC_BUILD_LINUX || defined CC_BUILD_BSD || defined CC_BUILD_SOLARIS
ReturnCode Platform_StartOpen(const String* args) {
/* TODO: Can this also be used on solaris, or is it just an OpenIndiana thing */
const static String path = String_FromConst("xdg-open");
return Platform_StartProcess(&path, args);
}
#endif
#ifdef CC_BUILD_LINUX
ReturnCode Platform_GetExePath(String* path) {
char str[600];
int len = readlink("/proc/self/exe", str, 600);
if (len == -1) return errno;
Convert_DecodeUtf8(path, str, len);
return 0;
}
#endif
#ifdef CC_BUILD_BSD
ReturnCode Platform_GetExePath(String* path) {
char str[600];
int mib[4];
size_t size = 600;
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_PATHNAME;
mib[3] = -1; /* self process id */
if (sysctl(mib, 4, str, &size, NULL, 0) == -1) return errno;
size = String_CalcLen(str, 600);
Convert_DecodeUtf8(path, str, size);
return 0;
}
#endif
#ifdef CC_BUILD_SOLARIS
ReturnCode Platform_GetExePath(String* path) {
char str[600];
int len = readlink("/proc/self/path/a.out", str, 600);
if (len == -1) return errno;
Convert_DecodeUtf8(path, str, len);
return 0;
}
#endif
#ifdef CC_BUILD_OSX
ReturnCode Platform_StartOpen(const String* args) {
const static String path = String_FromConst("/usr/bin/open");
return Platform_StartProcess(&path, args);
}
ReturnCode Platform_GetExePath(String* path) {
char str[600];
int len = 600;
if (_NSGetExecutablePath(str, &len) != 0) return ReturnCode_InvalidArg;
Convert_DecodeUtf8(path, str, len);
return 0;
}
#endif
void* Platform_GetSymbolFrom(const char* filename, const char* name) {
void* symbol;
void* lib;
String path;
ReturnCode res;
path = String_FromReadonly(filename);
res = Platform_LoadLibrary(&path, &lib);
if (res) return NULL;
res = Platform_GetSymbol(lib, name, &symbol);
return res ? NULL : symbol;
}
/*########################################################################################################################*
*--------------------------------------------------------Platform---------------------------------------------------------*
*#########################################################################################################################*/
@ -1912,71 +2104,6 @@ ReturnCode Platform_Decrypt(const uint8_t* data, int len, uint8_t** dec, int* de
LocalFree(dataOut.pbData);
return 0;
}
ReturnCode Platform_GetExePath(String* path) {
TCHAR chars[FILENAME_SIZE + 1];
DWORD len = GetModuleFileName(NULL, chars, FILENAME_SIZE);
if (!len) return GetLastError();
#ifdef UNICODE
Convert_DecodeUtf16(path, chars, len * 2);
#else
Convert_DecodeAscii(path, chars, len);
#endif
return 0;
}
ReturnCode Platform_StartProcess(const String* path, const String* args) {
String file, argv; char argvBuffer[300];
TCHAR str[300], raw[300];
STARTUPINFO si = { 0 };
PROCESS_INFORMATION pi = { 0 };
BOOL ok;
file = *path; Utils_UNSAFE_GetFilename(&file);
String_InitArray(argv, argvBuffer);
String_Format2(&argv, "\"%s\" %s", &file, args);
Platform_ConvertString(str, path);
Platform_ConvertString(raw, &argv);
si.cb = sizeof(STARTUPINFO);
ok = CreateProcess(str, raw, NULL, NULL, false, 0, NULL, NULL, &si, &pi);
if (!ok) return GetLastError();
/* Don't leak memory for proess return code */
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return 0;
}
ReturnCode Platform_StartOpen(const String* args) {
TCHAR str[300];
HINSTANCE instance;
Platform_ConvertString(str, args);
instance = ShellExecute(NULL, NULL, str, NULL, NULL, SW_SHOWNORMAL);
return instance > 32 ? 0 : (ReturnCode)instance;
}
/* Don't need special execute permission on windows */
ReturnCode Platform_MarkExecutable(const String* path) { return 0; }
ReturnCode Platform_LoadLibrary(const String* path, void** lib) {
TCHAR str[300];
Platform_ConvertString(str, path);
*lib = LoadLibrary(str);
return *lib ? 0 : GetLastError();
}
ReturnCode Platform_GetSymbol(void* lib, const char* name, void** symbol) {
*symbol = GetProcAddress(lib, name);
return *symbol ? 0 : GetLastError();
}
#else
ReturnCode Platform_Encrypt(const uint8_t* data, int len, uint8_t** enc, int* encLen) {
return ReturnCode_NotSupported;
}
ReturnCode Platform_Decrypt(const uint8_t* data, int len, uint8_t** dec, int* decLen) {
return ReturnCode_NotSupported;
}
#endif
#ifdef CC_BUILD_POSIX
int Platform_ConvertString(void* data, const String* src) {
@ -2025,60 +2152,11 @@ int Platform_GetCommandLineArgs(int argc, STRING_REF const char** argv, String*
return count;
}
ReturnCode Platform_StartProcess(const String* path, const String* args) {
char str[600], raw[600];
pid_t pid;
int i, j;
Platform_ConvertString(str, path);
Platform_ConvertString(raw, args);
pid = fork();
if (pid == -1) return errno;
if (pid == 0) {
/* Executed in child process */
char* argv[15];
argv[0] = str; argv[1] = raw;
/* need to null-terminate multiple arguments */
for (i = 0, j = 2; raw[i] && i < Array_Elems(raw); i++) {
if (raw[i] != ' ') continue;
/* null terminate previous argument */
raw[i] = '\0';
argv[j++] = &raw[i + 1];
}
argv[j] = NULL;
execvp(str, argv);
_exit(127); /* "command not found" */
} else {
/* Executed in parent process */
/* We do nothing here.. */
return 0;
}
ReturnCode Platform_Encrypt(const uint8_t* data, int len, uint8_t** enc, int* encLen) {
return ReturnCode_NotSupported;
}
ReturnCode Platform_MarkExecutable(const String* path) {
char str[600];
struct stat st;
Platform_ConvertString(str, path);
if (stat(str, &st) == -1) return errno;
st.st_mode |= S_IXUSR;
return chmod(str, st.st_mode) == -1 ? errno : 0;
}
ReturnCode Platform_LoadLibrary(const String* path, void** lib) {
char str[600];
Platform_ConvertString(str, path);
*lib = dlopen(str, RTLD_NOW);
return *lib == NULL;
}
ReturnCode Platform_GetSymbol(void* lib, const char* name, void** symbol) {
*symbol = dlsym(lib, name);
return *symbol == NULL; /* dlerror would be proper, but eh */
ReturnCode Platform_Decrypt(const uint8_t* data, int len, uint8_t** dec, int* decLen) {
return ReturnCode_NotSupported;
}
#endif
#ifdef CC_BUILD_X11
@ -2099,70 +2177,13 @@ static void Platform_InitDisplay(void) {
}
#endif
#if defined CC_BUILD_LINUX || defined CC_BUILD_BSD || defined CC_BUILD_SOLARIS
ReturnCode Platform_StartOpen(const String* args) {
/* TODO: Can this also be used on solaris, or is it just an OpenIndiana thing */
const static String path = String_FromConst("xdg-open");
return Platform_StartProcess(&path, args);
}
void Platform_Init(void) {
Platform_InitCommon();
/* stopwatch always in nanoseconds */
sw_freqDiv = 1000;
}
#endif
#ifdef CC_BUILD_LINUX
ReturnCode Platform_GetExePath(String* path) {
char str[600];
int len = readlink("/proc/self/exe", str, 600);
if (len == -1) return errno;
Convert_DecodeUtf8(path, str, len);
return 0;
}
#endif
#ifdef CC_BUILD_BSD
ReturnCode Platform_GetExePath(String* path) {
char str[600];
int mib[4];
size_t size = 600;
mib[0] = CTL_KERN;
mib[1] = KERN_PROC;
mib[2] = KERN_PROC_PATHNAME;
mib[3] = -1; /* self process id */
if (sysctl(mib, 4, str, &size, NULL, 0) == -1) return errno;
size = String_CalcLen(str, 600);
Convert_DecodeUtf8(path, str, size);
return 0;
}
#endif
#ifdef CC_BUILD_SOLARIS
ReturnCode Platform_GetExePath(String* path) {
char str[600];
int len = readlink("/proc/self/path/a.out", str, 600);
if (len == -1) return errno;
Convert_DecodeUtf8(path, str, len);
return 0;
}
#endif
#ifdef CC_BUILD_OSX
ReturnCode Platform_StartOpen(const String* args) {
const static String path = String_FromConst("/usr/bin/open");
return Platform_StartProcess(&path, args);
}
ReturnCode Platform_GetExePath(String* path) {
char str[600];
int len = 600;
if (_NSGetExecutablePath(str, &len) != 0) return ReturnCode_InvalidArg;
Convert_DecodeUtf8(path, str, len);
return 0;
}
static void Platform_InitDisplay(void) {
CGDirectDisplayID display = CGMainDisplayID();
CGRect bounds = CGDisplayBounds(display);

View File

@ -78,11 +78,16 @@ ReturnCode Platform_StartProcess(const String* path, const String* args);
ReturnCode Platform_StartOpen(const String* args);
/* Marks a file as being executable. */
ReturnCode Platform_MarkExecutable(const String* path);
/* Attempts to load a native dynamic library from the given path. */
CC_API ReturnCode Platform_LoadLibrary(const String* path, void** lib);
/* Attempts to get the address of the symbol in the given dynamic library. */
/* NOTE: Do NOT use this to load OpenGL functions, use GLContext_GetAddress. */
CC_API ReturnCode Platform_GetSymbol(void* lib, const char* name, void** symbol);
/* Simple wrapper for Platform_LoadLibrary then Platform_GetSymbol. */
/* NOTE: This should ONLY be used for dynamically loading platform-specific symbols. */
/* (e.g. functionality that only exists on recent operating system versions) */
void* Platform_GetSymbolFrom(const char* filename, const char* name);
/* Allocates a block of memory, with undetermined contents. Exits process on allocation failure. */
CC_API void* Mem_Alloc(uint32_t numElems, uint32_t elemsSize, const char* place);

View File

@ -100,92 +100,4 @@
}
}
#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
#define MAX_LENGTH 128
/* documentation is in ftmodapi.h */
FT_EXPORT_DEF( void )
FT_Set_Default_Properties( FT_Library library )
{
const char* env;
const char* p;
const char* q;
char module_name[MAX_LENGTH + 1];
char property_name[MAX_LENGTH + 1];
char property_value[MAX_LENGTH + 1];
int i;
env = ft_getenv( "FREETYPE_PROPERTIES" );
if ( !env )
return;
for ( p = env; *p; p++ )
{
/* skip leading whitespace and separators */
if ( *p == ' ' || *p == '\t' )
continue;
/* read module name, followed by `:' */
q = p;
for ( i = 0; i < MAX_LENGTH; i++ )
{
if ( !*p || *p == ':' )
break;
module_name[i] = *p++;
}
module_name[i] = '\0';
if ( !*p || *p != ':' || p == q )
break;
/* read property name, followed by `=' */
q = ++p;
for ( i = 0; i < MAX_LENGTH; i++ )
{
if ( !*p || *p == '=' )
break;
property_name[i] = *p++;
}
property_name[i] = '\0';
if ( !*p || *p != '=' || p == q )
break;
/* read property value, followed by whitespace (if any) */
q = ++p;
for ( i = 0; i < MAX_LENGTH; i++ )
{
if ( !*p || *p == ' ' || *p == '\t' )
break;
property_value[i] = *p++;
}
property_value[i] = '\0';
if ( !( *p == '\0' || *p == ' ' || *p == '\t' ) || p == q )
break;
/* we completely ignore errors */
ft_property_string_set( library,
module_name,
property_name,
property_value );
}
}
#else
FT_EXPORT_DEF( void )
FT_Set_Default_Properties( FT_Library library )
{
FT_UNUSED( library );
}
#endif
/* END */

View File

@ -81,10 +81,6 @@ FT_BEGIN_HEADER
/* FT_Remove_Module */
/* FT_Add_Default_Modules */
/* */
/* FT_Property_Set */
/* FT_Property_Get */
/* FT_Set_Default_Properties */
/* */
/* FT_New_Library */
/* FT_Done_Library */
/* FT_Reference_Library */
@ -290,179 +286,6 @@ FT_BEGIN_HEADER
FT_Module module );
/**********************************************************************
*
* @function:
* FT_Property_Set
*
* @description:
* Set a property for a given module.
*
* @input:
* library ::
* A handle to the library the module is part of.
*
* module_name ::
* The module name.
*
* property_name ::
* The property name. Properties are described in section
* @properties.
*
* Note that only a few modules have properties.
*
* value ::
* A generic pointer to a variable or structure that gives the new
* value of the property. The exact definition of `value' is
* dependent on the property; see section @properties.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* If `module_name' isn't a valid module name, or `property_name'
* doesn't specify a valid property, or if `value' doesn't represent a
* valid value for the given property, an error is returned.
*
* The following example sets property `bar' (a simple integer) in
* module `foo' to value~1.
*
* {
* FT_UInt bar;
*
*
* bar = 1;
* FT_Property_Set( library, "foo", "bar", &bar );
* }
*
* Note that the FreeType Cache sub-system doesn't recognize module
* property changes. To avoid glyph lookup confusion within the cache
* you should call @FTC_Manager_Reset to completely flush the cache if
* a module property gets changed after @FTC_Manager_New has been
* called.
*
* It is not possible to set properties of the FreeType Cache
* sub-system itself with FT_Property_Set; use @FTC_Property_Set
* instead.
*
* @since:
* 2.4.11
*
*/
FT_EXPORT( FT_Error )
FT_Property_Set( FT_Library library,
const FT_String* module_name,
const FT_String* property_name,
const void* value );
/**********************************************************************
*
* @function:
* FT_Property_Get
*
* @description:
* Get a module's property value.
*
* @input:
* library ::
* A handle to the library the module is part of.
*
* module_name ::
* The module name.
*
* property_name ::
* The property name. Properties are described in section
* @properties.
*
* @inout:
* value ::
* A generic pointer to a variable or structure that gives the
* value of the property. The exact definition of `value' is
* dependent on the property; see section @properties.
*
* @return:
* FreeType error code. 0~means success.
*
* @note:
* If `module_name' isn't a valid module name, or `property_name'
* doesn't specify a valid property, or if `value' doesn't represent a
* valid value for the given property, an error is returned.
*
* The following example gets property `baz' (a range) in module `foo'.
*
* {
* typedef range_
* {
* FT_Int32 min;
* FT_Int32 max;
*
* } range;
*
* range baz;
*
*
* FT_Property_Get( library, "foo", "baz", &baz );
* }
*
* It is not possible to retrieve properties of the FreeType Cache
* sub-system with FT_Property_Get; use @FTC_Property_Get instead.
*
* @since:
* 2.4.11
*
*/
FT_EXPORT( FT_Error )
FT_Property_Get( FT_Library library,
const FT_String* module_name,
const FT_String* property_name,
void* value );
/*************************************************************************/
/* */
/* <Function> */
/* FT_Set_Default_Properties */
/* */
/* <Description> */
/* If compilation option FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES is */
/* set, this function reads the `FREETYPE_PROPERTIES' environment */
/* variable to control driver properties. See section @properties */
/* for more. */
/* */
/* If the compilation option is not set, this function does nothing. */
/* */
/* `FREETYPE_PROPERTIES' has the following syntax form (broken here */
/* into multiple lines for better readability). */
/* */
/* { */
/* <optional whitespace> */
/* <module-name1> ':' */
/* <property-name1> '=' <property-value1> */
/* <whitespace> */
/* <module-name2> ':' */
/* <property-name2> '=' <property-value2> */
/* ... */
/* } */
/* */
/* Example: */
/* */
/* { */
/* FREETYPE_PROPERTIES=truetype:interpreter-version=35 \ */
/* cff:no-stem-darkening=1 \ */
/* autofitter:warping=1 */
/* } */
/* */
/* <InOut> */
/* library :: A handle to a new library object. */
/* */
/* <Since> */
/* 2.8 */
/* */
FT_EXPORT( void )
FT_Set_Default_Properties( FT_Library library );
/*************************************************************************/
/* */
/* <Function> */

View File

@ -3992,148 +3992,6 @@
}
static FT_Error
ft_property_do( FT_Library library,
const FT_String* module_name,
const FT_String* property_name,
void* value,
FT_Bool set,
FT_Bool value_is_string )
{
FT_Module* cur;
FT_Module* limit;
FT_Module_Interface interface;
FT_Service_Properties service;
#ifdef FT_DEBUG_LEVEL_ERROR
const FT_String* set_name = "FT_Property_Set";
const FT_String* get_name = "FT_Property_Get";
const FT_String* func_name = set ? set_name : get_name;
#endif
FT_Bool missing_func;
if ( !library )
return FT_THROW( Invalid_Library_Handle );
if ( !module_name || !property_name || !value )
return FT_THROW( Invalid_Argument );
cur = library->modules;
limit = cur + library->num_modules;
/* search module */
for ( ; cur < limit; cur++ )
if ( !ft_strcmp( cur[0]->clazz->module_name, module_name ) )
break;
if ( cur == limit )
{
FT_ERROR(( "%s: can't find module `%s'\n",
func_name, module_name ));
return FT_THROW( Missing_Module );
}
/* check whether we have a service interface */
if ( !cur[0]->clazz->get_interface )
{
FT_ERROR(( "%s: module `%s' doesn't support properties\n",
func_name, module_name ));
return FT_THROW( Unimplemented_Feature );
}
/* search property service */
interface = cur[0]->clazz->get_interface( cur[0],
FT_SERVICE_ID_PROPERTIES );
if ( !interface )
{
FT_ERROR(( "%s: module `%s' doesn't support properties\n",
func_name, module_name ));
return FT_THROW( Unimplemented_Feature );
}
service = (FT_Service_Properties)interface;
if ( set )
missing_func = (FT_Bool)( !service->set_property );
else
missing_func = (FT_Bool)( !service->get_property );
if ( missing_func )
{
FT_ERROR(( "%s: property service of module `%s' is broken\n",
func_name, module_name ));
return FT_THROW( Unimplemented_Feature );
}
return set ? service->set_property( cur[0],
property_name,
value,
value_is_string )
: service->get_property( cur[0],
property_name,
value );
}
/* documentation is in ftmodapi.h */
FT_EXPORT_DEF( FT_Error )
FT_Property_Set( FT_Library library,
const FT_String* module_name,
const FT_String* property_name,
const void* value )
{
return ft_property_do( library,
module_name,
property_name,
(void*)value,
TRUE,
FALSE );
}
/* documentation is in ftmodapi.h */
FT_EXPORT_DEF( FT_Error )
FT_Property_Get( FT_Library library,
const FT_String* module_name,
const FT_String* property_name,
void* value )
{
return ft_property_do( library,
module_name,
property_name,
value,
FALSE,
FALSE );
}
#ifdef FT_CONFIG_OPTION_ENVIRONMENT_PROPERTIES
/* this variant is used for handling the FREETYPE_PROPERTIES */
/* environment variable */
FT_BASE_DEF( FT_Error )
ft_property_string_set( FT_Library library,
const FT_String* module_name,
const FT_String* property_name,
FT_String* value )
{
return ft_property_do( library,
module_name,
property_name,
(void*)value,
TRUE,
TRUE );
}
#endif
/*************************************************************************/
/*************************************************************************/
/*************************************************************************/

View File

@ -110,7 +110,6 @@
#define ft_strtol strtol
#define ft_getenv getenv
/**********************************************************************/