diff options
author | tobigun <tobigun@b956fd51-792f-4845-bead-9b4dfca2ff2c> | 2010-05-23 09:07:15 +0000 |
---|---|---|
committer | tobigun <tobigun@b956fd51-792f-4845-bead-9b4dfca2ff2c> | 2010-05-23 09:07:15 +0000 |
commit | 678cc132f942ff4d84a803550eedf96acc543bca (patch) | |
tree | eb195abafaf69d55fa0f4b77323e517fcd2263cd /cmake/src/lib | |
parent | 7e677fd5ebe60c3dd9df8954e1ed28c4afdf8660 (diff) | |
download | usdx-678cc132f942ff4d84a803550eedf96acc543bca.tar.gz usdx-678cc132f942ff4d84a803550eedf96acc543bca.tar.xz usdx-678cc132f942ff4d84a803550eedf96acc543bca.zip |
update to trunk rev. 2391
git-svn-id: svn://svn.code.sf.net/p/ultrastardx/svn/branches/experimental@2401 b956fd51-792f-4845-bead-9b4dfca2ff2c
Diffstat (limited to '')
61 files changed, 15525 insertions, 1404 deletions
diff --git a/cmake/src/lib/FreeImage/FreeBitmap.pas b/cmake/src/lib/FreeImage/FreeBitmap.pas index 4e5f50a4..d32fb5cb 100644 --- a/cmake/src/lib/FreeImage/FreeBitmap.pas +++ b/cmake/src/lib/FreeImage/FreeBitmap.pas @@ -33,7 +33,7 @@ unit FreeBitmap; {$IFDEF FPC} {$MODE Delphi} - {$H+} // use AnsiString + {$H+} // use long strings {$ENDIF} interface diff --git a/cmake/src/lib/JEDI-SDL/OpenGL/Pas/glext.pas b/cmake/src/lib/JEDI-SDL/OpenGL/Pas/glext.pas index 1fc70f8a..871247a9 100644 --- a/cmake/src/lib/JEDI-SDL/OpenGL/Pas/glext.pas +++ b/cmake/src/lib/JEDI-SDL/OpenGL/Pas/glext.pas @@ -4282,32 +4282,33 @@ begin if (Pos(' ', extension) <> 0) or (extension = '') then begin - Result := FALSE; + Result := false; Exit; end; if searchIn = '' then extensions := glGetString(GL_EXTENSIONS) else - //StrLCopy( extensions, searchIn, StrLen(searchIn)+1 ); + //StrLCopy(extensions, searchIn, StrLen(searchIn) + 1); extensions := searchIn; start := extensions; - while TRUE do + while true do begin - where := StrPos(start, extension ); - if where = nil then Break; - terminator := Pointer(Integer(where) + Integer( strlen( extension ) ) ); - if (where = start) or (PChar(Integer(where) - 1)^ = ' ') then + where := StrPos(start, extension); + if where = nil then + Break; + terminator := where + Length(extension); + if (where = start) or ((where - 1)^ = ' ') then begin if (terminator^ = ' ') or (terminator^ = #0) then begin - Result := TRUE; + Result := true; Exit; end; end; start := terminator; end; - Result := FALSE; + Result := false; end; diff --git a/cmake/src/lib/JEDI-SDL/SDL/Pas/jedi-sdl.inc b/cmake/src/lib/JEDI-SDL/SDL/Pas/jedi-sdl.inc index fed972b5..31817d24 100644 --- a/cmake/src/lib/JEDI-SDL/SDL/Pas/jedi-sdl.inc +++ b/cmake/src/lib/JEDI-SDL/SDL/Pas/jedi-sdl.inc @@ -332,7 +332,7 @@ {$ELSE} {$DEFINE __OS_DOS__} {$ENDIF} - {$IFDEF WIN32} + {$IFDEF MSWINDOWS} {$DEFINE UseWin} {$ENDIF} {$DEFINE HAS_TYPES} @@ -380,13 +380,13 @@ {$OA+} // Objects and structures align {$ENDIF} -{$IFDEF Win32} +{$IFDEF MSWINDOWS} {$DEFINE OS_BigMem} -{$ELSE Win32} +{$ELSE MSWINDOWS} {$IFDEF ver70} {$DEFINE assembler} {$ENDIF} { use 16-bit assembler! } -{$ENDIF Win32} +{$ENDIF MSWINDOWS} { ************************** dos/dos-like platforms **************} {$IFDEF Windows} diff --git a/cmake/src/lib/JEDI-SDL/SDL/Pas/moduleloader.pas b/cmake/src/lib/JEDI-SDL/SDL/Pas/moduleloader.pas index ea4f220c..796aa0ab 100644 --- a/cmake/src/lib/JEDI-SDL/SDL/Pas/moduleloader.pas +++ b/cmake/src/lib/JEDI-SDL/SDL/Pas/moduleloader.pas @@ -59,7 +59,7 @@ interface // each OS gets its own IFDEFed complete code block to make reading easier -{$IFDEF WIN32} +{$IFDEF MSWINDOWS} uses Windows; diff --git a/cmake/src/lib/JEDI-SDL/SDL/Pas/sdl.pas b/cmake/src/lib/JEDI-SDL/SDL/Pas/sdl.pas index 0d7e46af..736009c2 100644 --- a/cmake/src/lib/JEDI-SDL/SDL/Pas/sdl.pas +++ b/cmake/src/lib/JEDI-SDL/SDL/Pas/sdl.pas @@ -370,7 +370,7 @@ const {$IFDEF DARWIN} SDLLibName = 'libSDL-1.2.0.dylib'; {$linklib libSDL-1.2.0} - {$linklib gcc} +// {$linklib gcc} {$linklib SDLmain} {$linkframework Cocoa} {$PASCALMAINNAME SDL_main} diff --git a/cmake/src/lib/Lua/ULua.pas b/cmake/src/lib/Lua/ULua.pas new file mode 100644 index 00000000..1de48a3c --- /dev/null +++ b/cmake/src/lib/Lua/ULua.pas @@ -0,0 +1,1086 @@ +unit ULua; + +(* + * A complete Pascal wrapper for Lua 5.1 DLL module. + * + * Created by Geo Massar, 2006 + * Distributed as free/open source. + *) + +interface + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +{$IFDEF UNIX} +uses + dl, + UConfig; +{$ENDIF} + +{$DEFINE LUA51} + +type + size_t = type Cardinal; + Psize_t = ^size_t; + PPointer = ^Pointer; + + lua_State = record end; + Plua_State = ^lua_State; + +const +{$IFDEF WIN32} + LuaDLL = 'lua5.1.dll'; +{$ENDIF} +{$IFDEF UNIX} +{$IFDEF DARWIN} + LuaDLL = 'liblua.5.1.dylib'; + {$linklib liblua.5.1} +{$ELSE} + LuaDLL = lua_lib_name; +{$ENDIF} +{$ENDIF} +{$IFDEF MACOS} + SDLgfxLibName = 'lua5.1'; +{$ENDIF} + +(* formats for Lua numbers *) +{$IFNDEF LUA_NUMBER_SCAN} +const + LUA_NUMBER_SCAN = '%lf'; +{$ENDIF} + +{$IFNDEF LUA_NUMBER_FMT} +const + LUA_NUMBER_FMT = '%.14g'; +{$ENDIF} + +(*****************************************************************************) +(* luaconfig.h *) +(*****************************************************************************) + +(* +** $Id: luaconf.h,v 1.81 2006/02/10 17:44:06 roberto Exp $ +** Configuration file for Lua +** See Copyright Notice in lua.h +*) + +(* +** {================================================================== +@@ LUA_NUMBER is the type of numbers in Lua. +** CHANGE the following definitions only if you want to build Lua +** with a number type different from double. You may also need to +** change lua_number2int & lua_number2integer. +** =================================================================== +*) +type + LUA_NUMBER_ = type Double; // ending underscore is needed in Pascal + LUA_INTEGER_ = type Integer; + +(* +@@ LUA_IDSIZE gives the maximum size for the description of the source +@* of a function in debug information. +** CHANGE it if you want a different size. +*) +const + LUA_IDSIZE = 60; + +(* +@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. +*) +const + LUAL_BUFFERSIZE = 1024; + +(* +@@ LUA_PROMPT is the default prompt used by stand-alone Lua. +@@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua. +** CHANGE them if you want different prompts. (You can also change the +** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.) +*) +const + LUA_PROMPT = '> '; + LUA_PROMPT2 = '>> '; + +(* +@@ lua_readline defines how to show a prompt and then read a line from +@* the standard input. +@@ lua_saveline defines how to "save" a read line in a "history". +@@ lua_freeline defines how to free a line read by lua_readline. +** CHANGE them if you want to improve this functionality (e.g., by using +** GNU readline and history facilities). +*) +function lua_readline(L : Plua_State; var b : PChar; p : PChar): Boolean; +procedure lua_saveline(L : Plua_State; idx : Integer); +procedure lua_freeline(L : Plua_State; b : PChar); + +(* +@@ lua_stdin_is_tty detects whether the standard input is a 'tty' (that +@* is, whether we're running lua interactively). +** CHANGE it if you have a better definition for non-POSIX/non-Windows +** systems. +*/ +#include <io.h> +#include <stdio.h> +#define lua_stdin_is_tty() _isatty(_fileno(stdin)) +*) +const + lua_stdin_is_tty = TRUE; + +(*****************************************************************************) +(* lua.h *) +(*****************************************************************************) + +(* +** $Id: lua.h,v 1.216 2006/01/10 12:50:13 roberto Exp $ +** Lua - An Extensible Extension Language +** Lua.org, PUC-Rio, Brazil (http://www.lua.org) +** See Copyright Notice at the end of this file +*) + +const + LUA_VERSION = 'Lua 5.1'; + LUA_VERSION_NUM = 501; + LUA_COPYRIGHT = 'Copyright (C) 1994-2006 Tecgraf, PUC-Rio'; + LUA_AUTHORS = 'R. Ierusalimschy, L. H. de Figueiredo & W. Celes'; + + (* mark for precompiled code (`<esc>Lua') *) + LUA_SIGNATURE = #27'Lua'; + + (* option for multiple returns in `lua_pcall' and `lua_call' *) + LUA_MULTRET = -1; + + (* + ** pseudo-indices + *) + LUA_REGISTRYINDEX = -10000; + LUA_ENVIRONINDEX = -10001; + LUA_GLOBALSINDEX = -10002; + +function lua_upvalueindex(idx : Integer) : Integer; // a marco + +const + (* thread status; 0 is OK *) + LUA_YIELD_ = 1; // Note: the ending underscore is needed in Pascal + LUA_ERRRUN = 2; + LUA_ERRSYNTAX = 3; + LUA_ERRMEM = 4; + LUA_ERRERR = 5; + +type + lua_CFunction = function(L : Plua_State) : Integer; cdecl; + + (* + ** functions that read/write blocks when loading/dumping Lua chunks + *) + lua_Reader = function (L : Plua_State; ud : Pointer; + sz : Psize_t) : PChar; cdecl; + lua_Writer = function (L : Plua_State; const p : Pointer; sz : size_t; + ud : Pointer) : Integer; cdecl; + + (* + ** prototype for memory-allocation functions + *) + lua_Alloc = function (ud, ptr : Pointer; + osize, nsize : size_t) : Pointer; cdecl; + +const + (* + ** basic types + *) + LUA_TNONE = -1; + + LUA_TNIL = 0; + LUA_TBOOLEAN = 1; + LUA_TLIGHTUSERDATA = 2; + LUA_TNUMBER = 3; + LUA_TSTRING = 4; + LUA_TTABLE = 5; + LUA_TFUNCTION = 6; + LUA_TUSERDATA = 7; + LUA_TTHREAD = 8; + + (* minimum Lua stack available to a C function *) + LUA_MINSTACK = 20; + +type + (* type of numbers in Lua *) + lua_Number = LUA_NUMBER_; + + (* type for integer functions *) + lua_Integer = LUA_INTEGER_; + +(* +** state manipulation +*) +function lua_newstate(f : lua_Alloc; ud : Pointer) : Plua_State; + cdecl; external LuaDLL; +procedure lua_close(L: Plua_State); + cdecl; external LuaDLL; +function lua_newthread(L : Plua_State) : Plua_State; + cdecl; external LuaDLL; + +function lua_atpanic(L : Plua_State; panicf : lua_CFunction) : lua_CFunction; + cdecl; external LuaDLL; + + +(* +** basic stack manipulation +*) +function lua_gettop(L : Plua_State) : Integer; + cdecl; external LuaDLL; +procedure lua_settop(L : Plua_State; idx : Integer); + cdecl; external LuaDLL; +procedure lua_pushvalue(L : Plua_State; idx : Integer); + cdecl; external LuaDLL; +procedure lua_remove(L : Plua_State; idx : Integer); + cdecl; external LuaDLL; +procedure lua_insert(L : Plua_State; idx : Integer); + cdecl; external LuaDLL; +procedure lua_replace(L : Plua_State; idx : Integer); + cdecl; external LuaDLL; +function lua_checkstack(L : Plua_State; sz : Integer) : LongBool; + cdecl; external LuaDLL; + +procedure lua_xmove(src, dest : Plua_State; n : Integer); + cdecl; external LuaDLL; + + +(* +** access functions (stack -> C) +*) +function lua_isnumber(L : Plua_State; idx : Integer) : LongBool; + cdecl; external LuaDLL; +function lua_isstring(L : Plua_State; idx : Integer) : LongBool; + cdecl; external LuaDLL; +function lua_iscfunction(L : Plua_State; idx : Integer) : LongBool; + cdecl; external LuaDLL; +function lua_isuserdata(L : Plua_State; idx : Integer) : LongBool; + cdecl; external LuaDLL; +function lua_type(L : Plua_State; idx : Integer) : Integer; + cdecl; external LuaDLL; +function lua_typename(L : Plua_State; tp : Integer) : PChar; + cdecl; external LuaDLL; + +function lua_equal(L : Plua_State; idx1, idx2 : Integer) : LongBool; + cdecl; external LuaDLL; +function lua_rawequal(L : Plua_State; idx1, idx2 : Integer) : LongBool; + cdecl; external LuaDLL; +function lua_lessthan(L : Plua_State; idx1, idx2 : Integer) : LongBool; + cdecl; external LuaDLL; + +function lua_tonumber(L : Plua_State; idx : Integer) : lua_Number; + cdecl; external LuaDLL; +function lua_tointeger(L : Plua_State; idx : Integer) : lua_Integer; + cdecl; external LuaDLL; +function lua_toboolean(L : Plua_State; idx : Integer) : LongBool; + cdecl; external LuaDLL; +function lua_tolstring(L : Plua_State; idx : Integer; + len : Psize_t) : PChar; + cdecl; external LuaDLL; +function lua_objlen(L : Plua_State; idx : Integer) : size_t; + cdecl; external LuaDLL; +function lua_tocfunction(L : Plua_State; idx : Integer) : lua_CFunction; + cdecl; external LuaDLL; +function lua_touserdata(L : Plua_State; idx : Integer) : Pointer; + cdecl; external LuaDLL; +function lua_tothread(L : Plua_State; idx : Integer) : Plua_State; + cdecl; external LuaDLL; +function lua_topointer(L : Plua_State; idx : Integer) : Pointer; + cdecl; external LuaDLL; + + +(* +** push functions (C -> stack) +*) +procedure lua_pushnil(L : Plua_State); + cdecl; external LuaDLL; +procedure lua_pushnumber(L : Plua_State; n : lua_Number); + cdecl; external LuaDLL; +procedure lua_pushinteger(L : Plua_State; n : lua_Integer); + cdecl; external LuaDLL; +procedure lua_pushlstring(L : Plua_State; const s : PChar; ls : size_t); + cdecl; external LuaDLL; +procedure lua_pushstring(L : Plua_State; const s : PChar); + cdecl; external LuaDLL; +function lua_pushvfstring(L : Plua_State; + const fmt : PChar; argp : Pointer) : PChar; + cdecl; external LuaDLL; +function lua_pushfstring(L : Plua_State; const fmt : PChar) : PChar; varargs; + cdecl; external LuaDLL; +procedure lua_pushcclosure(L : Plua_State; fn : lua_CFunction; n : Integer); + cdecl; external LuaDLL; +procedure lua_pushboolean(L : Plua_State; b : LongBool); + cdecl; external LuaDLL; +procedure lua_pushlightuserdata(L : Plua_State; p : Pointer); + cdecl; external LuaDLL; +function lua_pushthread(L : Plua_state) : Cardinal; + cdecl; external LuaDLL; + + +(* +** get functions (Lua -> stack) +*) +procedure lua_gettable(L : Plua_State ; idx : Integer); + cdecl; external LuaDLL; +procedure lua_getfield(L : Plua_State; idx : Integer; k : PChar); + cdecl; external LuaDLL; +procedure lua_rawget(L : Plua_State; idx : Integer); + cdecl; external LuaDLL; +procedure lua_rawgeti(L : Plua_State; idx, n : Integer); + cdecl; external LuaDLL; +procedure lua_createtable(L : Plua_State; narr, nrec : Integer); + cdecl; external LuaDLL; +function lua_newuserdata(L : Plua_State; sz : size_t) : Pointer; + cdecl; external LuaDLL; +function lua_getmetatable(L : Plua_State; objindex : Integer) : LongBool; + cdecl; external LuaDLL; +procedure lua_getfenv(L : Plua_State; idx : Integer); + cdecl; external LuaDLL; + + +(* +** set functions (stack -> Lua) +*) +procedure lua_settable(L : Plua_State; idx : Integer); + cdecl; external LuaDLL; +procedure lua_setfield(L : Plua_State; idx : Integer; const k : PChar); + cdecl; external LuaDLL; +procedure lua_rawset(L : Plua_State; idx : Integer); + cdecl; external LuaDLL; +procedure lua_rawseti(L : Plua_State; idx , n: Integer); + cdecl; external LuaDLL; +function lua_setmetatable(L : Plua_State; objindex : Integer): LongBool; + cdecl; external LuaDLL; +function lua_setfenv(L : Plua_State; idx : Integer): LongBool; + cdecl; external LuaDLL; + +(* +** `load' and `call' functions (load and run Lua code) +*) +procedure lua_call(L : Plua_State; nargs, nresults : Integer); + cdecl; external LuaDLL; +function lua_pcall(L : Plua_State; + nargs, nresults, errfunc : Integer) : Integer; + cdecl; external LuaDLL; +function lua_cpcall(L : Plua_State; + func : lua_CFunction; ud : Pointer) : Integer; + cdecl; external LuaDLL; +function lua_load(L : Plua_State; reader : lua_Reader; + dt : Pointer; const chunkname : PChar) : Integer; + cdecl; external LuaDLL; + +function lua_dump(L : Plua_State; writer : lua_Writer; data: Pointer) : Integer; + cdecl; external LuaDLL; + + +(* +** coroutine functions +*) +function lua_yield(L : Plua_State; nresults : Integer) : Integer; + cdecl; external LuaDLL; +function lua_resume(L : Plua_State; narg : Integer) : Integer; + cdecl; external LuaDLL; +function lua_status(L : Plua_State) : Integer; + cdecl; external LuaDLL; + +(* +** garbage-collection functions and options +*) +const + LUA_GCSTOP = 0; + LUA_GCRESTART = 1; + LUA_GCCOLLECT = 2; + LUA_GCCOUNT = 3; + LUA_GCCOUNTB = 4; + LUA_GCSTEP = 5; + LUA_GCSETPAUSE = 6; + LUA_GCSETSTEPMUL = 7; + +function lua_gc(L : Plua_State; what, data : Integer) : Integer; + cdecl; external LuaDLL; + +(* +** miscellaneous functions +*) +function lua_error(L : Plua_State) : Integer; + cdecl; external LuaDLL; + +function lua_next(L : Plua_State; idx : Integer) : Integer; + cdecl; external LuaDLL; + +procedure lua_concat(L : Plua_State; n : Integer); + cdecl; external LuaDLL; + +function lua_getallocf(L : Plua_State; ud : PPointer) : lua_Alloc; + cdecl; external LuaDLL; +procedure lua_setallocf(L : Plua_State; f : lua_Alloc; ud : Pointer); + cdecl; external LuaDLL; + +(* +** =============================================================== +** some useful macros +** =============================================================== +*) +procedure lua_pop(L : Plua_State; n : Integer); + +procedure lua_newtable(L : Plua_State); + +procedure lua_register(L : Plua_State; n : PChar; f : lua_CFunction); + +procedure lua_pushcfunction(L : Plua_State; f : lua_CFunction); + +function lua_strlen(L : Plua_State; idx : Integer) : Integer; + +function lua_isfunction(L : Plua_State; n : Integer) : Boolean; +function lua_istable(L : Plua_State; n : Integer) : Boolean; +function lua_islightuserdata(L : Plua_State; n : Integer) : Boolean; +function lua_isnil(L : Plua_State; n : Integer) : Boolean; +function lua_isboolean(L : Plua_State; n : Integer) : Boolean; +function lua_isthread(L : Plua_State; n : Integer) : Boolean; +function lua_isnone(L : Plua_State; n : Integer) : Boolean; +function lua_isnoneornil(L : Plua_State; n : Integer) : Boolean; + +procedure lua_pushliteral(L : Plua_State; s : PChar); + +procedure lua_setglobal(L : Plua_State; s : PChar); +procedure lua_getglobal(L : Plua_State; s : PChar); + +function lua_tostring(L : Plua_State; idx : Integer) : PChar; + + +(* +** compatibility macros and functions +*) +function lua_open : Plua_State; + +procedure lua_getregistry(L : Plua_State); + +function lua_getgccount(L : Plua_State) : Integer; + +type + lua_Chuckreader = type lua_Reader; + lua_Chuckwriter = type lua_Writer; + +(* ====================================================================== *) + +(* +** {====================================================================== +** Debug API +** ======================================================================= +*) + +(* +** Event codes +*) +const + LUA_HOOKCALL = 0; + LUA_HOOKRET = 1; + LUA_HOOKLINE = 2; + LUA_HOOKCOUNT = 3; + LUA_HOOKTAILRET = 4; + + +(* +** Event masks +*) + LUA_MASKCALL = 1 shl LUA_HOOKCALL; + LUA_MASKRET = 1 shl LUA_HOOKRET; + LUA_MASKLINE = 1 shl LUA_HOOKLINE; + LUA_MASKCOUNT = 1 shl LUA_HOOKCOUNT; + +type + lua_Debug = packed record + event : Integer; + name : PChar; (* (n) *) + namewhat : PChar; (* (n) `global', `local', `field', `method' *) + what : PChar; (* (S) `Lua', `C', `main', `tail' *) + source : PChar; (* (S) *) + currentline : Integer; (* (l) *) + nups : Integer; (* (u) number of upvalues *) + linedefined : Integer; (* (S) *) + short_src : array [0..LUA_IDSIZE-1] of Char; (* (S) *) + (* private part *) + i_ci : Integer; (* active function *) + end; + Plua_Debug = ^lua_Debug; + + (* Functions to be called by the debuger in specific events *) + lua_Hook = procedure (L : Plua_State; ar : Plua_Debug); cdecl; + + +function lua_getstack(L : Plua_State; level : Integer; + ar : Plua_Debug) : Integer; + cdecl; external LuaDLL; +function lua_getinfo(L : Plua_State; const what : PChar; + ar: Plua_Debug): Integer; + cdecl; external LuaDLL; +function lua_getlocal(L : Plua_State; + ar : Plua_Debug; n : Integer) : PChar; + cdecl; external LuaDLL; +function lua_setlocal(L : Plua_State; + ar : Plua_Debug; n : Integer) : PChar; + cdecl; external LuaDLL; +function lua_getupvalue(L : Plua_State; funcindex, n : Integer) : PChar; + cdecl; external LuaDLL; +function lua_setupvalue(L : Plua_State; funcindex, n : Integer) : PChar; + cdecl; external LuaDLL; + +function lua_sethook(L : Plua_State; func : lua_Hook; + mask, count: Integer): Integer; + cdecl; external LuaDLL; +{ +function lua_gethook(L : Plua_State) : lua_Hook; + cdecl; external LuaDLL; +} +function lua_gethookmask(L : Plua_State) : Integer; + cdecl; external LuaDLL; +function lua_gethookcount(L : Plua_State) : Integer; + cdecl; external LuaDLL; + + +(*****************************************************************************) +(* lualib.h *) +(*****************************************************************************) + +(* +** $Id: lualib.h,v 1.36 2005/12/27 17:12:00 roberto Exp $ +** Lua standard libraries +** See Copyright Notice at the end of this file +*) + +const + (* Key to file-handle type *) + LUA_FILEHANDLE = 'FILE*'; + + LUA_COLIBNAME = 'coroutine'; + LUA_TABLIBNAME = 'table'; + LUA_IOLIBNAME = 'io'; + LUA_OSLIBNAME = 'os'; + LUA_STRLIBNAME = 'string'; + LUA_MATHLIBNAME = 'math'; + LUA_DBLIBNAME = 'debug'; + LUA_LOADLIBNAME = 'package'; + +function luaopen_base(L : Plua_State) : Integer; + cdecl; external LuaDLL; + +function luaopen_table(L : Plua_State) : Integer; + cdecl; external LuaDLL; + +function luaopen_io(L : Plua_State) : Integer; + cdecl; external LuaDLL; + +function luaopen_os(L : Plua_State) : Integer; + cdecl; external LuaDLL; + +function luaopen_string(L : Plua_State) : Integer; + cdecl; external LuaDLL; + +function luaopen_math(L : Plua_State) : Integer; + cdecl; external LuaDLL; + +function luaopen_debug(L : Plua_State) : Integer; + cdecl; external LuaDLL; + +function luaopen_package(L : Plua_State) : Integer; + cdecl; external LuaDLL; + +procedure luaL_openlibs(L : Plua_State); + cdecl; external LuaDLL; + +procedure lua_assert(x : Boolean); // a macro + + +(*****************************************************************************) +(* lauxlib.h *) +(*****************************************************************************) + +(* +** $Id: lauxlib.h,v 1.87 2005/12/29 15:32:11 roberto Exp $ +** Auxiliary functions for building Lua libraries +** See Copyright Notice at the end of this file. +*) + +// not compatibility with the behavior of setn/getn in Lua 5.0 +function luaL_getn(L : Plua_State; idx : Integer) : Integer; +procedure luaL_setn(L : Plua_State; i, j : Integer); + +const + LUA_ERRFILE = LUA_ERRERR + 1; + +type + luaL_Reg = packed record + name : PChar; + func : lua_CFunction; + end; + PluaL_Reg = ^luaL_Reg; + + +procedure luaL_openlib(L : Plua_State; const libname : PChar; + const lr : PluaL_Reg; nup : Integer); + cdecl; external LuaDLL; +procedure luaL_register(L : Plua_State; const libname : PChar; + const lr : PluaL_Reg); + cdecl; external LuaDLL; +function luaL_getmetafield(L : Plua_State; obj : Integer; + const e : PChar) : Integer; + cdecl; external LuaDLL; +function luaL_callmeta(L : Plua_State; obj : Integer; + const e : PChar) : Integer; + cdecl; external LuaDLL; +function luaL_typerror(L : Plua_State; narg : Integer; + const tname : PChar) : Integer; + cdecl; external LuaDLL; +function luaL_argerror(L : Plua_State; numarg : Integer; + const extramsg : PChar) : Integer; + cdecl; external LuaDLL; +function luaL_checklstring(L : Plua_State; numArg : Integer; + ls : Psize_t) : PChar; + cdecl; external LuaDLL; +function luaL_optlstring(L : Plua_State; numArg : Integer; + const def: PChar; ls: Psize_t) : PChar; + cdecl; external LuaDLL; +function luaL_checknumber(L : Plua_State; numArg : Integer) : lua_Number; + cdecl; external LuaDLL; +function luaL_optnumber(L : Plua_State; nArg : Integer; + def : lua_Number) : lua_Number; + cdecl; external LuaDLL; + +function luaL_checkinteger(L : Plua_State; numArg : Integer) : lua_Integer; + cdecl; external LuaDLL; +function luaL_optinteger(L : Plua_State; nArg : Integer; + def : lua_Integer) : lua_Integer; + cdecl; external LuaDLL; + +procedure luaL_checkstack(L : Plua_State; sz : Integer; const msg : PChar); + cdecl; external LuaDLL; +procedure luaL_checktype(L : Plua_State; narg, t : Integer); + cdecl; external LuaDLL; +procedure luaL_checkany(L : Plua_State; narg : Integer); + cdecl; external LuaDLL; + +function luaL_newmetatable(L : Plua_State; const tname : PChar) : Integer; + cdecl; external LuaDLL; +function luaL_checkudata(L : Plua_State; ud : Integer; + const tname : PChar) : Pointer; + cdecl; external LuaDLL; + +procedure luaL_where(L : Plua_State; lvl : Integer); + cdecl; external LuaDLL; +function luaL_error(L : Plua_State; const fmt : PChar) : Integer; varargs; + cdecl; external LuaDLL; + +function luaL_checkoption(L : Plua_State; narg : Integer; const def : PChar; + const lst : array of PChar) : Integer; + cdecl; external LuaDLL; + +function luaL_ref(L : Plua_State; t : Integer) : Integer; + cdecl; external LuaDLL; +procedure luaL_unref(L : Plua_State; t, ref : Integer); + cdecl; external LuaDLL; + +function luaL_loadfile(L : Plua_State; const filename : PChar) : Integer; + cdecl; external LuaDLL; +function luaL_loadbuffer(L : Plua_State; const buff : PChar; + sz : size_t; const name: PChar) : Integer; + cdecl; external LuaDLL; + +function luaL_loadstring(L : Plua_State; const s : Pchar) : Integer; + cdecl; external LuaDLL; + +function luaL_newstate : Plua_State; + cdecl; external LuaDLL; + +function luaL_gsub(L : Plua_State; const s, p, r : PChar) : PChar; + cdecl; external LuaDLL; + +function luaL_findtable(L : Plua_State; idx : Integer; + const fname : PChar; szhint : Integer) : PChar; + cdecl; external LuaDLL; + + +(* +** =============================================================== +** some useful macros +** =============================================================== +*) + +function luaL_argcheck(L : Plua_State; cond : Boolean; numarg : Integer; + extramsg : PChar): Integer; +function luaL_checkstring(L : Plua_State; n : Integer) : PChar; +function luaL_optstring(L : Plua_State; n : Integer; d : PChar) : PChar; +function luaL_checkint(L : Plua_State; n : Integer) : Integer; +function luaL_optint(L : Plua_State; n, d : Integer): Integer; +function luaL_checklong(L : Plua_State; n : LongInt) : LongInt; +function luaL_optlong(L : Plua_State; n : Integer; d : LongInt) : LongInt; + +function luaL_typename(L : Plua_State; idx : Integer) : PChar; + +function luaL_dofile(L : Plua_State; fn : PChar) : Integer; + +function luaL_dostring(L : Plua_State; s : PChar) : Integer; + +procedure luaL_getmetatable(L : Plua_State; n : PChar); + +(* not implemented yet +#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) +*) + +(* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*) + +type + luaL_Buffer = packed record + p : PChar; (* current position in buffer *) + lvl : Integer; (* number of strings in the stack (level) *) + L : Plua_State; + buffer : array [0..LUAL_BUFFERSIZE-1] of Char; + end; + PluaL_Buffer = ^luaL_Buffer; + +procedure luaL_addchar(B : PluaL_Buffer; c : Char); + +(* compatibility only *) +procedure luaL_putchar(B : PluaL_Buffer; c : Char); + +procedure luaL_addsize(B : PluaL_Buffer; n : Integer); + +procedure luaL_buffinit(L : Plua_State; B : PluaL_Buffer); + cdecl; external LuaDLL; +function luaL_prepbuffer(B : PluaL_Buffer) : PChar; + cdecl; external LuaDLL; +procedure luaL_addlstring(B : PluaL_Buffer; const s : PChar; ls : size_t); + cdecl; external LuaDLL; +procedure luaL_addstring(B : PluaL_Buffer; const s : PChar); + cdecl; external LuaDLL; +procedure luaL_addvalue(B : PluaL_Buffer); + cdecl; external LuaDLL; +procedure luaL_pushresult(B : PluaL_Buffer); + cdecl; external LuaDLL; + +(* ====================================================== *) + + +(* compatibility with ref system *) + +(* pre-defined references *) +const + LUA_NOREF = -2; + LUA_REFNIL = -1; + +function lua_ref(L : Plua_State; lock : Boolean) : Integer; + +procedure lua_unref(L : Plua_State; ref : Integer); + +procedure lua_getref(L : Plua_State; ref : Integer); + + +(******************************************************************************) +(******************************************************************************) +(******************************************************************************) + +implementation + +uses + SysUtils; + +(*****************************************************************************) +(* luaconfig.h *) +(*****************************************************************************) + +function lua_readline(L : Plua_State; var b : PChar; p : PChar): Boolean; +var + s : AnsiString; +begin + Write(p); // show prompt + ReadLn(s); // get line + b := PChar(s); // and return it + lua_readline := (b[0] <> #4); // test for ctrl-D +end; + +procedure lua_saveline(L : Plua_State; idx : Integer); +begin +end; + +procedure lua_freeline(L : Plua_State; b : PChar); +begin +end; + + +(*****************************************************************************) +(* lua.h *) +(*****************************************************************************) + +function lua_upvalueindex(idx : Integer) : Integer; +begin + lua_upvalueindex := LUA_GLOBALSINDEX - idx; +end; + +procedure lua_pop(L : Plua_State; n : Integer); +begin + lua_settop(L, -n - 1); +end; + +procedure lua_newtable(L : Plua_State); +begin + lua_createtable(L, 0, 0); +end; + +procedure lua_register(L : Plua_State; n : PChar; f : lua_CFunction); +begin + lua_pushcfunction(L, f); + lua_setglobal(L, n); +end; + +procedure lua_pushcfunction(L : Plua_State; f : lua_CFunction); +begin + lua_pushcclosure(L, f, 0); +end; + +function lua_strlen(L : Plua_State; idx : Integer) : Integer; +begin + lua_strlen := lua_objlen(L, idx); +end; + +function lua_isfunction(L : Plua_State; n : Integer) : Boolean; +begin + lua_isfunction := lua_type(L, n) = LUA_TFUNCTION; +end; + +function lua_istable(L : Plua_State; n : Integer) : Boolean; +begin + lua_istable := lua_type(L, n) = LUA_TTABLE; +end; + +function lua_islightuserdata(L : Plua_State; n : Integer) : Boolean; +begin + lua_islightuserdata := lua_type(L, n) = LUA_TLIGHTUSERDATA; +end; + +function lua_isnil(L : Plua_State; n : Integer) : Boolean; +begin + lua_isnil := lua_type(L, n) = LUA_TNIL; +end; + +function lua_isboolean(L : Plua_State; n : Integer) : Boolean; +begin + lua_isboolean := lua_type(L, n) = LUA_TBOOLEAN; +end; + +function lua_isthread(L : Plua_State; n : Integer) : Boolean; +begin + lua_isthread := lua_type(L, n) = LUA_TTHREAD; +end; + +function lua_isnone(L : Plua_State; n : Integer) : Boolean; +begin + lua_isnone := lua_type(L, n) = LUA_TNONE; +end; + +function lua_isnoneornil(L : Plua_State; n : Integer) : Boolean; +begin + lua_isnoneornil := lua_type(L, n) <= 0; +end; + +procedure lua_pushliteral(L : Plua_State; s : PChar); +begin + lua_pushlstring(L, s, StrLen(s)); +end; + +procedure lua_setglobal(L : Plua_State; s : PChar); +begin + lua_setfield(L, LUA_GLOBALSINDEX, s); +end; + +procedure lua_getglobal(L: Plua_State; s: PChar); +begin + lua_getfield(L, LUA_GLOBALSINDEX, s); +end; + +function lua_tostring(L : Plua_State; idx : Integer) : PChar; +begin + lua_tostring := lua_tolstring(L, idx, nil); +end; + +function lua_open : Plua_State; +begin + lua_open := luaL_newstate; +end; + +procedure lua_getregistry(L : Plua_State); +begin + lua_pushvalue(L, LUA_REGISTRYINDEX); +end; + +function lua_getgccount(L : Plua_State) : Integer; +begin + lua_getgccount := lua_gc(L, LUA_GCCOUNT, 0); +end; + + +(*****************************************************************************) +(* lualib.h *) +(*****************************************************************************) + +procedure lua_assert(x : Boolean); +begin +end; + + +(*****************************************************************************) +(* lauxlib.h n *) +(*****************************************************************************) + +function luaL_getn(L : Plua_State; idx : Integer) : Integer; +begin + luaL_getn := lua_objlen(L, idx); +end; + +procedure luaL_setn(L : plua_State; i, j : Integer); +begin + (* no op *) +end; + +function luaL_argcheck(L : Plua_State; cond : Boolean; numarg : Integer; + extramsg : PChar): Integer; +begin + if not cond then + luaL_argcheck := luaL_argerror(L, numarg, extramsg) + else + luaL_argcheck := 0; +end; + +function luaL_checkstring(L : Plua_State; n : Integer) : PChar; +begin + luaL_checkstring := luaL_checklstring(L, n, nil); +end; + +function luaL_optstring(L : Plua_State; n : Integer; d : PChar) : PChar; +begin + luaL_optstring := luaL_optlstring(L, n, d, nil); +end; + +function luaL_checkint(L : Plua_State; n : Integer) : Integer; +begin + luaL_checkint := luaL_checkinteger(L, n); +end; + +function luaL_optint(L : Plua_State; n, d : Integer): Integer; +begin + luaL_optint := luaL_optinteger(L, n, d); +end; + +function luaL_checklong(L : Plua_State; n : LongInt) : LongInt; +begin + luaL_checklong := luaL_checkinteger(L, n); +end; + +function luaL_optlong(L : Plua_State; n : Integer; d : LongInt) : LongInt; +begin + luaL_optlong := luaL_optinteger(L, n, d); +end; + +function luaL_typename(L : Plua_State; idx : Integer) : PChar; +begin + luaL_typename := lua_typename( L, lua_type(L, idx) ); +end; + +function luaL_dofile(L : Plua_State; fn : PChar) : Integer; +Var + Res : Integer; +begin + // WC 2007\03\22 - Updated for Delphi + Res := luaL_loadfile(L, fn); + if Res = 0 then + Res := lua_pcall(L, 0, LUA_MULTRET, 0); + Result := Res; +end; + +function luaL_dostring(L : Plua_State; s : PChar) : Integer; +Var + Res : Integer; +begin + // WC 2007\03\22 - Updated for Delphi + Res := luaL_loadstring(L, s); + if Res = 0 then + Res := lua_pcall(L, 0, LUA_MULTRET, 0); + Result := Res; +end; + +procedure luaL_getmetatable(L : Plua_State; n : PChar); +begin + lua_getfield(L, LUA_REGISTRYINDEX, n); +end; + +procedure luaL_addchar(B : PluaL_Buffer; c : Char); +begin + if not(B^.p < B^.buffer + LUAL_BUFFERSIZE) then + luaL_prepbuffer(B); + B^.p^ := c; + Inc(B^.p); +end; + +procedure luaL_putchar(B : PluaL_Buffer; c : Char); +begin + luaL_addchar(B, c); +end; + +procedure luaL_addsize(B : PluaL_Buffer; n : Integer); +begin + Inc(B^.p, n); +end; + +function lua_ref(L : Plua_State; lock : Boolean) : Integer; +begin + if lock then + lua_ref := luaL_ref(L, LUA_REGISTRYINDEX) + else begin + lua_pushstring(L, 'unlocked references are obsolete'); + lua_error(L); + lua_ref := 0; + end; +end; + +procedure lua_unref(L : Plua_State; ref : Integer); +begin + luaL_unref(L, LUA_REGISTRYINDEX, ref); +end; + +procedure lua_getref(L : Plua_State; ref : Integer); +begin + lua_rawgeti(L, LUA_REGISTRYINDEX, ref); +end; + + +(****************************************************************************** +* Original copyright for the lua source and headers: +* 1994-2004 Tecgraf, PUC-Rio. +* www.lua.org. +* +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be +* included in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +******************************************************************************) + +end. + diff --git a/cmake/src/lib/SQLite/SQLite3.pas b/cmake/src/lib/SQLite/SQLite3.pas index 9537606c..7b7207c4 100644 --- a/cmake/src/lib/SQLite/SQLite3.pas +++ b/cmake/src/lib/SQLite/SQLite3.pas @@ -10,7 +10,7 @@ unit SQLite3; {$IFDEF FPC} {$MODE DELPHI} - {$H+} (* use AnsiString *) + {$H+} (* use long strings *) {$PACKENUM 4} (* use 4-byte enums *) {$PACKRECORDS C} (* C/C++-compatible record packing *) {$ELSE} diff --git a/cmake/src/lib/SQLite/SQLiteTable3.pas b/cmake/src/lib/SQLite/SQLiteTable3.pas index 7df76363..3aed54a4 100644 --- a/cmake/src/lib/SQLite/SQLiteTable3.pas +++ b/cmake/src/lib/SQLite/SQLiteTable3.pas @@ -139,6 +139,7 @@ type procedure Commit; procedure Rollback; function TableExists(TableName: string): boolean; + function ContainsColumn(Table: String; Column: String) : boolean; function GetLastInsertRowID: int64; function GetLastChangedRows: int64; procedure SetTimeout(Value: integer); @@ -759,6 +760,26 @@ begin end; end; +function TSQLiteDatabase.ContainsColumn(Table: String; Column: String) : boolean; +var + sql: string; + ds: TSqliteTable; + i : integer; +begin + sql := 'PRAGMA TABLE_INFO('+Table+');'; + ds := self.GetTable(sql); + try + Result := false; + while (ds.Next() and not Result and not ds.EOF) do + begin + if ds.FieldAsString(1) = Column then + Result := true; + end; + finally + ds.Free; + end; +end; + procedure TSQLiteDatabase.SetTimeout(Value: integer); begin SQLite3_BusyTimeout(self.fDB, Value); diff --git a/cmake/src/lib/TntUnicodeControls/License.txt b/cmake/src/lib/TntUnicodeControls/License.txt new file mode 100644 index 00000000..8ac7f75b --- /dev/null +++ b/cmake/src/lib/TntUnicodeControls/License.txt @@ -0,0 +1,11 @@ +TntWare Delphi Unicode Controls + http://www.tntware.com/delphicontrols/unicode/ + +Copyright (c) 2002-2007, Troy Wolbrink (www.tntware.com) + +License +Redistribution and use in binary forms, with or without modification, are permitted. Redistribution and use in source forms, with or without modification, are permitted provided that the redistributions of source code retain the above copyright. + +Disclaimer +This software is provided by the author "as is" and any express or implied warranties, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose are disclaimed. In no event shall the author be liable for any direct, indirect, incidental, special, exemplary, or consequential damages (including, but not limited to, procurement of substitute goods or services; loss of use, data, or profits; or business interruption) however caused and on any theory of liability, whether in contract, strict liability, or tort (including negligence or otherwise) arising in any way out of the use of this software, even if advised of the possibility of such damage. + diff --git a/cmake/src/lib/TntUnicodeControls/Readme.txt b/cmake/src/lib/TntUnicodeControls/Readme.txt new file mode 100644 index 00000000..a2d8f799 --- /dev/null +++ b/cmake/src/lib/TntUnicodeControls/Readme.txt @@ -0,0 +1,53 @@ + ** Tnt Delphi UNICODE Controls Project ** + +Website: http://tnt.ccci.org/delphi_unicode_controls/ +Email: troy.wolbrink@ccci.org + +These controls are provided as-is, with no implied warranty. They are freely available for you to use in your own projects. Please let me know if you have found them helpful. Also, please let me know if you find any bugs or other areas of needed improvement. + + +---Delphi Installation-------------------------- + +The most simple way to install these components is by opening the appropriate design package in Delphi and clicking on the big "Install" button. For instance, Delphi 5's design package is TntUnicodeVcl_D50.dpk. + +For BCB 2006 and newer, open the appropriate design package in the packages\bcbx\ folder using the Delphi personality. After compiling and installing, you should be able to use the components in both the Delphi and BCB personality. Remember to set the library path in menu "Tools->Options" for both the C++ Builder and the Delphi. + + +---A note on fonts---------------------- + +The default TFont uses "MS Sans Serif" which doesn't work well with most non-ANSI characters. I'd recommend using a TrueType font such as "Tahoma" if it is installed on the machine. To make TFont use a different font like "Tahoma" add this to the first line in the project: + + Graphics.DefFontData.Name := 'Tahoma'; + +You might have to include "Graphics" in the file's uses clauses. Furthermore, adding this line of code to the project will cause the changed setting to only be applied at runtime, not at design time. To make a designtime change, you'd have to add this line to the initialization section of a unit in a design package. + +Regarding the IDE, I use GExperts to change the font of the Object Inspector. The Wide String List editor uses the font used by the object inspector. + +Also keep in mind that the font used by certain message boxes come from that set by Windows' Display properties. + + +---Background---------------------------- + +Designing software for an international audience, I've always wanted to write a full UNICODE application. My approach so far, has been to write Unicode on the inside, and MBCS on the outside. This has always been frustrating, because (even on Windows NT/2000/XP which provide native Unicode window controls) the WideStrings inside my application and databases were always confined to an ANSI VCL. And, since the VCL was designed to wrap the low-level Windows details, why shouldn't the VCL hide the fact that sometimes native Unicode controls are not possible on the given version of Windows. I believe the VCL should be written with a Unicode interface, even if it must (at times) deal with an ANSI operating system. For example, TEdit should expose Text as a WideString, even if it has to convert the WideString to an AnsiString on the Windows 9X platform. + +In the past, the ANSI VCL may have made a little sense, considering that there were many more users of Windows 9X, than Windows NT. There would have been some performance penalty to use WideStrings on the Windows 9X platform. But with the faster computers of today, and with more people using platforms such as Windows 2000 and Windows XP, the ANSI VCL just doesn't make sense anymore. In fact, having to use the the ANSI VCL on Windows NT/2000/XP is slower because of the constant conversion to and from UNICODE inside Windows. + +My coding signature is Tnt. I will use this to denote my classes from others. + +For more information about me: <http://home.ccci.org/wolbrink/> +Some of my software projects (all written in Delphi). + TntMPD (contact manager for missionaries) + <http://www.tntmpd.com/> + Jesus Film Screen Saver + <http://home.ccci.org/wolbrink/screensaver.htm> + ActiveX SCR control + <http://tnt.ccci.org/download/activex_scr/ActiveXSCR.exe> + +---Design Goals---------------------------- + +I want the controls to work on Windows 95, 98, ME, NT, 2000, XP, etc. I want a single EXE for all platforms. Of course, full UNICODE support is only truly available on NT/2000/XP. In other words, the controls should automatically scale to take advantage of native Unicode support when possible. + +I want the controls to inherit from the Delphi VCL. I want to reuse as much code as possible. For the most part this makes sense. The only sticky part is where text messages get passed around. But I believe I've gotten past this through strategic subclassing at various points in the message flow chain. To give a rough comparison of why this is so important, check out the following chart which compares the lines of code in the VCL for a given control (4,397 in all), and the lines of code required in my descendent controls (655 in all). Besides saving lines of code, I get the advantage of automatically inheriting new features as new versions of Delphi come out. One such example is the AlphaBlending feature in the Delphi 6 TForm. Even though I use Delphi 5 now, I won't have to add any code to get this new feature. + +---More Interesting Information---------------------------- +Case Study: Porting an MFC Application to Unicode: It looks like the FrontPage 2002 team did the roughly the same thing to MFC as what I'm doing to the VCL. They did this with the same goal in mind: to support Unicode as much as possible depending on the support offered by Windows. Another goal was "Don’t abandon MFC; don’t rewrite app". Because they still want to support Windows 9X using the same worldwide EXE used everywhere. They couldn't just compile with the _UNICODE directive. They had to start with the ANSI MFC, strategically subclassing window procedures at just the right places. Hmmm... sounds familiar.
\ No newline at end of file diff --git a/cmake/src/lib/TntUnicodeControls/TntClasses.pas b/cmake/src/lib/TntUnicodeControls/TntClasses.pas new file mode 100644 index 00000000..f0ebd14c --- /dev/null +++ b/cmake/src/lib/TntUnicodeControls/TntClasses.pas @@ -0,0 +1,1806 @@ +
+{*****************************************************************************}
+{ }
+{ Tnt Delphi Unicode Controls }
+{ http://www.tntware.com/delphicontrols/unicode/ }
+{ Version: 2.3.0 }
+{ }
+{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) }
+{ }
+{*****************************************************************************}
+
+unit TntClasses;
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$INCLUDE TntCompilers.inc}
+
+interface
+
+{ TODO: Consider: TTntRegIniFile, TTntMemIniFile (consider if UTF8 fits into this solution). }
+
+{***********************************************}
+{ WideChar-streaming implemented by Maël Hörz }
+{***********************************************}
+
+uses
+ Classes, SysUtils, Windows,
+ {$IFNDEF COMPILER_10_UP}
+ TntWideStrings,
+ {$ELSE}
+ WideStrings,
+ {$ENDIF}
+ ActiveX, Contnrs;
+
+// ......... introduced .........
+type
+ TTntStreamCharSet = (csAnsi, csUnicode, csUnicodeSwapped, csUtf8);
+
+function AutoDetectCharacterSet(Stream: TStream): TTntStreamCharSet;
+
+//---------------------------------------------------------------------------------------------
+// Tnt - Classes
+//---------------------------------------------------------------------------------------------
+
+{TNT-WARN ExtractStrings}
+{TNT-WARN LineStart}
+{TNT-WARN TStringStream} // TODO: Implement a TWideStringStream
+
+// A potential implementation of TWideStringStream can be found at:
+// http://kdsxml.cvs.sourceforge.net/kdsxml/Global/KDSClasses.pas?revision=1.10&view=markup
+
+procedure TntPersistent_AfterInherited_DefineProperties(Filer: TFiler; Instance: TPersistent);
+
+type
+{TNT-WARN TFileStream}
+ TTntFileStream = class(THandleStream)
+ public
+ constructor Create(const FileName: WideString; Mode: Word);
+ destructor Destroy; override;
+ end;
+
+{TNT-WARN TMemoryStream}
+ TTntMemoryStream = class(TMemoryStream{TNT-ALLOW TMemoryStream})
+ public
+ procedure LoadFromFile(const FileName: WideString);
+ procedure SaveToFile(const FileName: WideString);
+ end;
+
+{TNT-WARN TResourceStream}
+ TTntResourceStream = class(TCustomMemoryStream)
+ private
+ HResInfo: HRSRC;
+ HGlobal: THandle;
+ procedure Initialize(Instance: THandle; Name, ResType: PWideChar);
+ public
+ constructor Create(Instance: THandle; const ResName: WideString; ResType: PWideChar);
+ constructor CreateFromID(Instance: THandle; ResID: Word; ResType: PWideChar);
+ destructor Destroy; override;
+ function Write(const Buffer; Count: Longint): Longint; override;
+ procedure SaveToFile(const FileName: WideString);
+ end;
+
+ TTntStrings = class;
+
+{TNT-WARN TAnsiStrings}
+ TAnsiStrings{TNT-ALLOW TAnsiStrings} = class(TStrings{TNT-ALLOW TStrings})
+ public
+ procedure LoadFromFile(const FileName: WideString); reintroduce;
+ procedure SaveToFile(const FileName: WideString); reintroduce;
+ procedure LoadFromFileEx(const FileName: WideString; CodePage: Cardinal);
+ procedure SaveToFileEx(const FileName: WideString; CodePage: Cardinal);
+ procedure LoadFromStreamEx(Stream: TStream; CodePage: Cardinal); virtual; abstract;
+ procedure SaveToStreamEx(Stream: TStream; CodePage: Cardinal); virtual; abstract;
+ end;
+
+ TAnsiStringsForWideStringsAdapter = class(TAnsiStrings{TNT-ALLOW TAnsiStrings})
+ private
+ FWideStrings: TTntStrings;
+ FAdapterCodePage: Cardinal;
+ protected
+ function Get(Index: Integer): AnsiString; override;
+ procedure Put(Index: Integer; const S: AnsiString); override;
+ function GetCount: Integer; override;
+ function GetObject(Index: Integer): TObject; override;
+ procedure PutObject(Index: Integer; AObject: TObject); override;
+ procedure SetUpdateState(Updating: Boolean); override;
+ function AdapterCodePage: Cardinal; dynamic;
+ public
+ constructor Create(AWideStrings: TTntStrings; _AdapterCodePage: Cardinal = 0);
+ procedure Clear; override;
+ procedure Delete(Index: Integer); override;
+ procedure Insert(Index: Integer; const S: AnsiString); override;
+ procedure LoadFromStreamEx(Stream: TStream; CodePage: Cardinal); override;
+ procedure SaveToStreamEx(Stream: TStream; CodePage: Cardinal); override;
+ end;
+
+{TNT-WARN TStrings}
+ TTntStrings = class(TWideStrings)
+ private
+ FLastFileCharSet: TTntStreamCharSet;
+ FAnsiStrings: TAnsiStrings{TNT-ALLOW TAnsiStrings};
+ procedure SetAnsiStrings(const Value: TAnsiStrings{TNT-ALLOW TAnsiStrings});
+ procedure ReadData(Reader: TReader);
+ procedure ReadDataUTF7(Reader: TReader);
+ procedure ReadDataUTF8(Reader: TReader);
+ procedure WriteDataUTF7(Writer: TWriter);
+ protected
+ procedure DefineProperties(Filer: TFiler); override;
+ public
+ constructor Create;
+ destructor Destroy; override;
+
+ procedure LoadFromFile(const FileName: WideString); override;
+ procedure LoadFromStream(Stream: TStream); override;
+ procedure LoadFromStream_BOM(Stream: TStream; WithBOM: Boolean); virtual;
+
+ procedure SaveToFile(const FileName: WideString); override;
+ procedure SaveToStream(Stream: TStream); override;
+ procedure SaveToStream_BOM(Stream: TStream; WithBOM: Boolean); virtual;
+
+ property LastFileCharSet: TTntStreamCharSet read FLastFileCharSet;
+ published
+ property AnsiStrings: TAnsiStrings{TNT-ALLOW TAnsiStrings} read FAnsiStrings write SetAnsiStrings stored False;
+ end;
+
+{ TTntStringList class }
+
+ TTntStringList = class;
+ TWideStringListSortCompare = function(List: TTntStringList; Index1, Index2: Integer): Integer;
+
+{TNT-WARN TStringList}
+ TTntStringList = class(TTntStrings)
+ private
+ FUpdating: Boolean;
+ FList: PWideStringItemList;
+ FCount: Integer;
+ FCapacity: Integer;
+ FSorted: Boolean;
+ FDuplicates: TDuplicates;
+ FCaseSensitive: Boolean;
+ FOnChange: TNotifyEvent;
+ FOnChanging: TNotifyEvent;
+ procedure ExchangeItems(Index1, Index2: Integer);
+ procedure Grow;
+ procedure QuickSort(L, R: Integer; SCompare: TWideStringListSortCompare);
+ procedure SetSorted(Value: Boolean);
+ procedure SetCaseSensitive(const Value: Boolean);
+ protected
+ procedure Changed; virtual;
+ procedure Changing; virtual;
+ function Get(Index: Integer): WideString; override;
+ function GetCapacity: Integer; override;
+ function GetCount: Integer; override;
+ function GetObject(Index: Integer): TObject; override;
+ procedure Put(Index: Integer; const S: WideString); override;
+ procedure PutObject(Index: Integer; AObject: TObject); override;
+ procedure SetCapacity(NewCapacity: Integer); override;
+ procedure SetUpdateState(Updating: Boolean); override;
+ function CompareStrings(const S1, S2: WideString): Integer; override;
+ procedure InsertItem(Index: Integer; const S: WideString; AObject: TObject); virtual;
+ public
+ destructor Destroy; override;
+ function Add(const S: WideString): Integer; override;
+ function AddObject(const S: WideString; AObject: TObject): Integer; override;
+ procedure Clear; override;
+ procedure Delete(Index: Integer); override;
+ procedure Exchange(Index1, Index2: Integer); override;
+ function Find(const S: WideString; var Index: Integer): Boolean; virtual;
+ function IndexOf(const S: WideString): Integer; override;
+ function IndexOfName(const Name: WideString): Integer; override;
+ procedure Insert(Index: Integer; const S: WideString); override;
+ procedure InsertObject(Index: Integer; const S: WideString;
+ AObject: TObject); override;
+ procedure Sort; virtual;
+ procedure CustomSort(Compare: TWideStringListSortCompare); virtual;
+ property Duplicates: TDuplicates read FDuplicates write FDuplicates;
+ property Sorted: Boolean read FSorted write SetSorted;
+ property CaseSensitive: Boolean read FCaseSensitive write SetCaseSensitive;
+ property OnChange: TNotifyEvent read FOnChange write FOnChange;
+ property OnChanging: TNotifyEvent read FOnChanging write FOnChanging;
+ end;
+
+// ......... introduced .........
+type
+ TListTargetCompare = function (Item, Target: Pointer): Integer;
+
+function FindSortedListByTarget(List: TList; TargetCompare: TListTargetCompare;
+ Target: Pointer; var Index: Integer): Boolean;
+
+function ClassIsRegistered(const clsid: TCLSID): Boolean;
+
+var
+ RuntimeUTFStreaming: Boolean;
+
+type
+ TBufferedAnsiString = class(TObject)
+ private
+ FStringBuffer: AnsiString;
+ LastWriteIndex: Integer;
+ public
+ procedure Clear;
+ procedure AddChar(const wc: AnsiChar);
+ procedure AddString(const s: AnsiString);
+ procedure AddBuffer(Buff: PAnsiChar; Chars: Integer);
+ function Value: AnsiString;
+ function BuffPtr: PAnsiChar;
+ end;
+
+ TBufferedWideString = class(TObject)
+ private
+ FStringBuffer: WideString;
+ LastWriteIndex: Integer;
+ public
+ procedure Clear;
+ procedure AddChar(const wc: WideChar);
+ procedure AddString(const s: WideString);
+ procedure AddBuffer(Buff: PWideChar; Chars: Integer);
+ function Value: WideString;
+ function BuffPtr: PWideChar;
+ end;
+
+ TBufferedStreamReader = class(TStream)
+ private
+ FStream: TStream;
+ FStreamSize: Integer;
+ FBuffer: array of Byte;
+ FBufferSize: Integer;
+ FBufferStartPosition: Integer;
+ FVirtualPosition: Integer;
+ procedure UpdateBufferFromPosition(StartPos: Integer);
+ public
+ constructor Create(Stream: TStream; BufferSize: Integer = 1024);
+ function Read(var Buffer; Count: Longint): Longint; override;
+ function Write(const Buffer; Count: Longint): Longint; override;
+ function Seek(Offset: Longint; Origin: Word): Longint; override;
+ end;
+
+// "synced" wide string
+type TSetAnsiStrEvent = procedure(const Value: AnsiString) of object;
+function GetSyncedWideString(var WideStr: WideString; const AnsiStr: AnsiString): WideString;
+procedure SetSyncedWideString(const Value: WideString; var WideStr: WideString;
+ const AnsiStr: AnsiString; SetAnsiStr: TSetAnsiStrEvent);
+
+type
+ TWideComponentHelper = class(TComponent)
+ private
+ FComponent: TComponent;
+ protected
+ procedure Notification(AComponent: TComponent; Operation: TOperation); override;
+ public
+ constructor Create(AOwner: TComponent); override;
+ constructor CreateHelper(AOwner: TComponent; ComponentHelperList: TComponentList);
+ end;
+
+function FindWideComponentHelper(ComponentHelperList: TComponentList; Component: TComponent): TWideComponentHelper;
+
+implementation
+
+uses
+ RTLConsts, ComObj, Math,
+ Registry, TypInfo, TntSystem, TntSysUtils;
+
+{ TntPersistent }
+
+//===========================================================================
+// The Delphi 5 Classes.pas never supported the streaming of WideStrings.
+// The Delphi 6 Classes.pas supports WideString streaming. But it's too bad that
+// the Delphi 6 IDE doesn't use the updated Classes.pas. Switching between Form/Text
+// mode corrupts extended characters in WideStrings even under Delphi 6.
+// Delphi 7 seems to finally get right. But let's keep the UTF7 support at design time
+// to enable sharing source code with previous versions of Delphi.
+//
+// The purpose of this solution is to store WideString properties which contain
+// non-ASCII chars in the form of UTF7 under the old property name + '_UTF7'.
+//
+// Special thanks go to Francisco Leong for helping to develop this solution.
+//
+
+{ TTntWideStringPropertyFiler }
+type
+ TTntWideStringPropertyFiler = class
+ private
+ FInstance: TPersistent;
+ FPropInfo: PPropInfo;
+ procedure ReadDataUTF8(Reader: TReader);
+ procedure ReadDataUTF7(Reader: TReader);
+ procedure WriteDataUTF7(Writer: TWriter);
+ public
+ procedure DefineProperties(Filer: TFiler; Instance: TPersistent; PropName: AnsiString);
+ end;
+
+function ReaderNeedsUtfHelp(Reader: TReader): Boolean;
+begin
+ if Reader.Owner = nil then
+ Result := False { designtime - visual form inheritance ancestor }
+ else if csDesigning in Reader.Owner.ComponentState then
+ {$IFDEF COMPILER_7_UP}
+ Result := False { Delphi 7+: designtime - doesn't need UTF help. }
+ {$ELSE}
+ Result := True { Delphi 6: designtime - always needs UTF help. }
+ {$ENDIF}
+ else
+ Result := RuntimeUTFStreaming; { runtime }
+end;
+
+procedure TTntWideStringPropertyFiler.ReadDataUTF8(Reader: TReader);
+begin
+ if ReaderNeedsUtfHelp(Reader) then
+ SetWideStrProp(FInstance, FPropInfo, UTF8ToWideString(Reader.ReadString))
+ else
+ Reader.ReadString; { do nothing with Result }
+end;
+
+procedure TTntWideStringPropertyFiler.ReadDataUTF7(Reader: TReader);
+begin
+ if ReaderNeedsUtfHelp(Reader) then
+ SetWideStrProp(FInstance, FPropInfo, UTF7ToWideString(Reader.ReadString))
+ else
+ Reader.ReadString; { do nothing with Result }
+end;
+
+procedure TTntWideStringPropertyFiler.WriteDataUTF7(Writer: TWriter);
+begin
+ Writer.WriteString(WideStringToUTF7(GetWideStrProp(FInstance, FPropInfo)));
+end;
+
+procedure TTntWideStringPropertyFiler.DefineProperties(Filer: TFiler; Instance: TPersistent;
+ PropName: AnsiString);
+
+ {$IFNDEF COMPILER_7_UP}
+ function HasData: Boolean;
+ var
+ CurrPropValue: WideString;
+ begin
+ // must be stored
+ Result := IsStoredProp(Instance, FPropInfo);
+ if Result
+ and (Filer.Ancestor <> nil)
+ and (GetPropInfo(Filer.Ancestor, PropName, [tkWString]) <> nil) then
+ begin
+ // must be different than ancestor
+ CurrPropValue := GetWideStrProp(Instance, FPropInfo);
+ Result := CurrPropValue <> GetWideStrProp(Filer.Ancestor, GetPropInfo(Filer.Ancestor, PropName));
+ end;
+ if Result then begin
+ // must be non-blank and different than UTF8 (implies all ASCII <= 127)
+ CurrPropValue := GetWideStrProp(Instance, FPropInfo);
+ Result := (CurrPropValue <> '') and (WideStringToUTF8(CurrPropValue) <> CurrPropValue);
+ end;
+ end;
+ {$ENDIF}
+
+begin
+ FInstance := Instance;
+ FPropInfo := GetPropInfo(Instance, PropName, [tkWString]);
+ if FPropInfo <> nil then begin
+ // must be published (and of type WideString)
+ Filer.DefineProperty(PropName + 'W', ReadDataUTF8, nil, False);
+ {$IFDEF COMPILER_7_UP}
+ Filer.DefineProperty(PropName + '_UTF7', ReadDataUTF7, WriteDataUTF7, False);
+ {$ELSE}
+ Filer.DefineProperty(PropName + '_UTF7', ReadDataUTF7, WriteDataUTF7, HasData);
+ {$ENDIF}
+ end;
+ FInstance := nil;
+ FPropInfo := nil;
+end;
+
+{ TTntWideCharPropertyFiler }
+type
+ TTntWideCharPropertyFiler = class
+ private
+ FInstance: TPersistent;
+ FPropInfo: PPropInfo;
+ {$IFNDEF COMPILER_9_UP}
+ FWriter: TWriter;
+ procedure GetLookupInfo(var Ancestor: TPersistent;
+ var Root, LookupRoot, RootAncestor: TComponent);
+ {$ENDIF}
+ procedure ReadData_W(Reader: TReader);
+ procedure ReadDataUTF7(Reader: TReader);
+ procedure WriteData_W(Writer: TWriter);
+ function ReadChar(Reader: TReader): WideChar;
+ public
+ procedure DefineProperties(Filer: TFiler; Instance: TPersistent; PropName: AnsiString);
+ end;
+
+{$IFNDEF COMPILER_9_UP}
+type
+ TGetLookupInfoEvent = procedure(var Ancestor: TPersistent;
+ var Root, LookupRoot, RootAncestor: TComponent) of object;
+
+function AncestorIsValid(Ancestor: TPersistent; Root, RootAncestor: TComponent): Boolean;
+begin
+ Result := (Ancestor <> nil) and (RootAncestor <> nil) and
+ Root.InheritsFrom(RootAncestor.ClassType);
+end;
+
+function IsDefaultOrdPropertyValue(Instance: TObject; PropInfo: PPropInfo;
+ OnGetLookupInfo: TGetLookupInfoEvent): Boolean;
+var
+ Ancestor: TPersistent;
+ LookupRoot: TComponent;
+ RootAncestor: TComponent;
+ Root: TComponent;
+ AncestorValid: Boolean;
+ Value: Longint;
+ Default: LongInt;
+begin
+ Ancestor := nil;
+ Root := nil;
+ LookupRoot := nil;
+ RootAncestor := nil;
+
+ if Assigned(OnGetLookupInfo) then
+ OnGetLookupInfo(Ancestor, Root, LookupRoot, RootAncestor);
+
+ AncestorValid := AncestorIsValid(Ancestor, Root, RootAncestor);
+
+ Result := True;
+ if (PropInfo^.GetProc <> nil) and (PropInfo^.SetProc <> nil) then
+ begin
+ Value := GetOrdProp(Instance, PropInfo);
+ if AncestorValid then
+ Result := Value = GetOrdProp(Ancestor, PropInfo)
+ else
+ begin
+ Default := PPropInfo(PropInfo)^.Default;
+ Result := (Default <> LongInt($80000000)) and (Value = Default);
+ end;
+ end;
+end;
+
+procedure TTntWideCharPropertyFiler.GetLookupInfo(var Ancestor: TPersistent;
+ var Root, LookupRoot, RootAncestor: TComponent);
+begin
+ Ancestor := FWriter.Ancestor;
+ Root := FWriter.Root;
+ LookupRoot := FWriter.LookupRoot;
+ RootAncestor := FWriter.RootAncestor;
+end;
+{$ENDIF}
+
+function TTntWideCharPropertyFiler.ReadChar(Reader: TReader): WideChar;
+var
+ Temp: WideString;
+begin
+ case Reader.NextValue of
+ vaWString:
+ Temp := Reader.ReadWideString;
+ vaString:
+ Temp := Reader.ReadString;
+ else
+ raise EReadError.Create(SInvalidPropertyValue);
+ end;
+
+ if Length(Temp) > 1 then
+ raise EReadError.Create(SInvalidPropertyValue);
+ Result := Temp[1];
+end;
+
+procedure TTntWideCharPropertyFiler.ReadData_W(Reader: TReader);
+begin
+ SetOrdProp(FInstance, FPropInfo, Ord(ReadChar(Reader)));
+end;
+
+procedure TTntWideCharPropertyFiler.ReadDataUTF7(Reader: TReader);
+var
+ S: WideString;
+begin
+ S := UTF7ToWideString(Reader.ReadString);
+ if S = '' then
+ SetOrdProp(FInstance, FPropInfo, 0)
+ else
+ SetOrdProp(FInstance, FPropInfo, Ord(S[1]))
+end;
+
+type TAccessWriter = class(TWriter);
+
+procedure TTntWideCharPropertyFiler.WriteData_W(Writer: TWriter);
+var
+ L: Integer;
+ Temp: WideString;
+{$IFDEF FPC}
+// Workaround: the Buffer parameter of TWriter.Write() must be of a fixed size
+// type for FPC >= 2.4.0. The values vaWString, Ord(vaWString) or Integer(vaWString)
+// are not allowed anymore.
+const
+ vaWStringInt: integer = Ord(vaWString);
+{$ENDIF}
+begin
+ Temp := WideChar(GetOrdProp(FInstance, FPropInfo));
+
+ {$IFNDEF FPC}
+ TAccessWriter(Writer).WriteValue(vaWString);
+ {$ELSE}
+ TAccessWriter(Writer).Write(vaWStringInt, SizeOf(vaWString));
+ {$ENDIF}
+ L := Length(Temp);
+ Writer.Write(L, SizeOf(Integer));
+ Writer.Write(Pointer(@Temp[1])^, L * 2);
+end;
+
+procedure TTntWideCharPropertyFiler.DefineProperties(Filer: TFiler;
+ Instance: TPersistent; PropName: AnsiString);
+
+ {$IFNDEF COMPILER_9_UP}
+ function HasData: Boolean;
+ var
+ CurrPropValue: Integer;
+ begin
+ // must be stored
+ Result := IsStoredProp(Instance, FPropInfo);
+ if Result and (Filer.Ancestor <> nil) and
+ (GetPropInfo(Filer.Ancestor, PropName, [tkWChar]) <> nil) then
+ begin
+ // must be different than ancestor
+ CurrPropValue := GetOrdProp(Instance, FPropInfo);
+ Result := CurrPropValue <> GetOrdProp(Filer.Ancestor, GetPropInfo(Filer.Ancestor, PropName));
+ end;
+ if Result and (Filer is TWriter) then
+ begin
+ FWriter := TWriter(Filer);
+ Result := not IsDefaultOrdPropertyValue(Instance, FPropInfo, GetLookupInfo);
+ end;
+ end;
+ {$ENDIF}
+
+begin
+ FInstance := Instance;
+ FPropInfo := GetPropInfo(Instance, PropName, [tkWChar]);
+ if FPropInfo <> nil then
+ begin
+ // must be published (and of type WideChar)
+ {$IFDEF COMPILER_9_UP}
+ Filer.DefineProperty(PropName + 'W', ReadData_W, WriteData_W, False);
+ {$ELSE}
+ Filer.DefineProperty(PropName + 'W', ReadData_W, WriteData_W, HasData);
+ {$ENDIF}
+ Filer.DefineProperty(PropName + '_UTF7', ReadDataUTF7, nil, False);
+ end;
+ FInstance := nil;
+ FPropInfo := nil;
+end;
+
+procedure TntPersistent_AfterInherited_DefineProperties(Filer: TFiler; Instance: TPersistent);
+var
+ I, Count: Integer;
+ PropInfo: PPropInfo;
+ PropList: PPropList;
+ WideStringFiler: TTntWideStringPropertyFiler;
+ WideCharFiler: TTntWideCharPropertyFiler;
+begin
+ Count := GetTypeData(Instance.ClassInfo)^.PropCount;
+ if Count > 0 then
+ begin
+ WideStringFiler := TTntWideStringPropertyFiler.Create;
+ try
+ WideCharFiler := TTntWideCharPropertyFiler.Create;
+ try
+ GetMem(PropList, Count * SizeOf(Pointer));
+ try
+ GetPropInfos(Instance.ClassInfo, PropList);
+ for I := 0 to Count - 1 do
+ begin
+ PropInfo := PropList^[I];
+ if (PropInfo = nil) then
+ break;
+ if (PropInfo.PropType^.Kind = tkWString) then
+ WideStringFiler.DefineProperties(Filer, Instance, PropInfo.Name)
+ else if (PropInfo.PropType^.Kind = tkWChar) then
+ WideCharFiler.DefineProperties(Filer, Instance, PropInfo.Name)
+ end;
+ finally
+ FreeMem(PropList, Count * SizeOf(Pointer));
+ end;
+ finally
+ WideCharFiler.Free;
+ end;
+ finally
+ WideStringFiler.Free;
+ end;
+ end;
+end;
+
+{ TTntFileStream }
+
+{$IFDEF FPC}
+ {$DEFINE HAS_SFCREATEERROREX}
+{$ENDIF}
+{$IFDEF DELPHI_7_UP}
+ {$DEFINE HAS_SFCREATEERROREX}
+{$ENDIF}
+
+constructor TTntFileStream.Create(const FileName: WideString; Mode: Word);
+var
+ CreateHandle: Integer;
+ {$IFDEF HAS_SFCREATEERROREX}
+ ErrorMessage: WideString;
+ {$ENDIF}
+begin
+ if Mode = fmCreate then
+ begin
+ CreateHandle := WideFileCreate(FileName);
+ if CreateHandle < 0 then begin
+ {$IFDEF HAS_SFCREATEERROREX}
+ ErrorMessage := WideSysErrorMessage(GetLastError);
+ raise EFCreateError.CreateFmt(SFCreateErrorEx, [WideExpandFileName(FileName), ErrorMessage]);
+ {$ELSE}
+ raise EFCreateError.CreateFmt(SFCreateError, [WideExpandFileName(FileName)]);
+ {$ENDIF}
+ end;
+ end else
+ begin
+ CreateHandle := WideFileOpen(FileName, Mode);
+ if CreateHandle < 0 then begin
+ {$IFDEF HAS_SFCREATEERROREX}
+ ErrorMessage := WideSysErrorMessage(GetLastError);
+ raise EFOpenError.CreateFmt(SFOpenErrorEx, [WideExpandFileName(FileName), ErrorMessage]);
+ {$ELSE}
+ raise EFOpenError.CreateFmt(SFOpenError, [WideExpandFileName(FileName)]);
+ {$ENDIF}
+ end;
+ end;
+ inherited Create(CreateHandle);
+end;
+
+destructor TTntFileStream.Destroy;
+begin
+ if Handle >= 0 then FileClose(Handle);
+end;
+
+{ TTntMemoryStream }
+
+procedure TTntMemoryStream.LoadFromFile(const FileName: WideString);
+var
+ Stream: TStream;
+begin
+ Stream := TTntFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
+ try
+ LoadFromStream(Stream);
+ finally
+ Stream.Free;
+ end;
+end;
+
+procedure TTntMemoryStream.SaveToFile(const FileName: WideString);
+var
+ Stream: TStream;
+begin
+ Stream := TTntFileStream.Create(FileName, fmCreate);
+ try
+ SaveToStream(Stream);
+ finally
+ Stream.Free;
+ end;
+end;
+
+{ TTntResourceStream }
+
+constructor TTntResourceStream.Create(Instance: THandle; const ResName: WideString;
+ ResType: PWideChar);
+begin
+ inherited Create;
+ Initialize(Instance, PWideChar(ResName), ResType);
+end;
+
+constructor TTntResourceStream.CreateFromID(Instance: THandle; ResID: Word;
+ ResType: PWideChar);
+begin
+ inherited Create;
+ Initialize(Instance, PWideChar(ResID), ResType);
+end;
+
+procedure TTntResourceStream.Initialize(Instance: THandle; Name, ResType: PWideChar);
+
+ procedure Error;
+ begin
+ raise EResNotFound.CreateFmt(SResNotFound, [Name]);
+ end;
+
+begin
+ HResInfo := FindResourceW(Instance, Name, ResType);
+ if HResInfo = 0 then Error;
+ HGlobal := LoadResource(Instance, HResInfo);
+ if HGlobal = 0 then Error;
+ SetPointer(LockResource(HGlobal), SizeOfResource(Instance, HResInfo));
+end;
+
+destructor TTntResourceStream.Destroy;
+begin
+ UnlockResource(HGlobal);
+ FreeResource(HGlobal); { Technically this is not necessary (MS KB #193678) }
+ inherited Destroy;
+end;
+
+function TTntResourceStream.Write(const Buffer; Count: Longint): Longint;
+begin
+ raise EStreamError.CreateRes(PResStringRec(@SCantWriteResourceStreamError));
+end;
+
+procedure TTntResourceStream.SaveToFile(const FileName: WideString);
+var
+ Stream: TStream;
+begin
+ Stream := TTntFileStream.Create(FileName, fmCreate);
+ try
+ SaveToStream(Stream);
+ finally
+ Stream.Free;
+ end;
+end;
+
+{ TAnsiStrings }
+
+procedure TAnsiStrings{TNT-ALLOW TAnsiStrings}.LoadFromFile(const FileName: WideString);
+var
+ Stream: TStream;
+begin
+ Stream := TTntFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
+ try
+ LoadFromStream(Stream);
+ finally
+ Stream.Free;
+ end;
+end;
+
+procedure TAnsiStrings{TNT-ALLOW TAnsiStrings}.SaveToFile(const FileName: WideString);
+var
+ Stream: TStream;
+begin
+ Stream := TTntFileStream.Create(FileName, fmCreate);
+ try
+ SaveToStream(Stream);
+ finally
+ Stream.Free;
+ end;
+end;
+
+procedure TAnsiStrings{TNT-ALLOW TAnsiStrings}.LoadFromFileEx(const FileName: WideString; CodePage: Cardinal);
+var
+ Stream: TStream;
+begin
+ Stream := TTntFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
+ try
+ LoadFromStreamEx(Stream, CodePage);
+ finally
+ Stream.Free;
+ end;
+end;
+
+procedure TAnsiStrings{TNT-ALLOW TAnsiStrings}.SaveToFileEx(const FileName: WideString; CodePage: Cardinal);
+var
+ Stream: TStream;
+ Utf8BomPtr: PAnsiChar;
+begin
+ Stream := TTntFileStream.Create(FileName, fmCreate);
+ try
+ if (CodePage = CP_UTF8) then
+ begin
+ Utf8BomPtr := PAnsiChar(UTF8_BOM);
+ Stream.WriteBuffer(Utf8BomPtr^, Length(UTF8_BOM));
+ end;
+ SaveToStreamEx(Stream, CodePage);
+ finally
+ Stream.Free;
+ end;
+end;
+
+{ TAnsiStringsForWideStringsAdapter }
+
+constructor TAnsiStringsForWideStringsAdapter.Create(AWideStrings: TTntStrings; _AdapterCodePage: Cardinal);
+begin
+ inherited Create;
+ FWideStrings := AWideStrings;
+ FAdapterCodePage := _AdapterCodePage;
+end;
+
+function TAnsiStringsForWideStringsAdapter.AdapterCodePage: Cardinal;
+begin
+ if FAdapterCodePage = 0 then
+ Result := TntSystem.DefaultSystemCodePage
+ else
+ Result := FAdapterCodePage;
+end;
+
+procedure TAnsiStringsForWideStringsAdapter.Clear;
+begin
+ FWideStrings.Clear;
+end;
+
+procedure TAnsiStringsForWideStringsAdapter.Delete(Index: Integer);
+begin
+ FWideStrings.Delete(Index);
+end;
+
+function TAnsiStringsForWideStringsAdapter.Get(Index: Integer): AnsiString;
+begin
+ Result := WideStringToStringEx(FWideStrings.Get(Index), AdapterCodePage);
+end;
+
+procedure TAnsiStringsForWideStringsAdapter.Put(Index: Integer; const S: AnsiString);
+begin
+ FWideStrings.Put(Index, StringToWideStringEx(S, AdapterCodePage));
+end;
+
+function TAnsiStringsForWideStringsAdapter.GetCount: Integer;
+begin
+ Result := FWideStrings.GetCount;
+end;
+
+procedure TAnsiStringsForWideStringsAdapter.Insert(Index: Integer; const S: AnsiString);
+begin
+ FWideStrings.Insert(Index, StringToWideStringEx(S, AdapterCodePage));
+end;
+
+function TAnsiStringsForWideStringsAdapter.GetObject(Index: Integer): TObject;
+begin
+ Result := FWideStrings.GetObject(Index);
+end;
+
+procedure TAnsiStringsForWideStringsAdapter.PutObject(Index: Integer; AObject: TObject);
+begin
+ FWideStrings.PutObject(Index, AObject);
+end;
+
+procedure TAnsiStringsForWideStringsAdapter.SetUpdateState(Updating: Boolean);
+begin
+ FWideStrings.SetUpdateState(Updating);
+end;
+
+procedure TAnsiStringsForWideStringsAdapter.LoadFromStreamEx(Stream: TStream; CodePage: Cardinal);
+var
+ Size: Integer;
+ S: AnsiString;
+begin
+ BeginUpdate;
+ try
+ Size := Stream.Size - Stream.Position;
+ SetString(S, nil, Size);
+ Stream.Read(Pointer(S)^, Size);
+ FWideStrings.SetTextStr(StringToWideStringEx(S, CodePage));
+ finally
+ EndUpdate;
+ end;
+end;
+
+procedure TAnsiStringsForWideStringsAdapter.SaveToStreamEx(Stream: TStream; CodePage: Cardinal);
+var
+ S: AnsiString;
+begin
+ S := WideStringToStringEx(FWideStrings.GetTextStr, CodePage);
+ Stream.WriteBuffer(Pointer(S)^, Length(S));
+end;
+
+{ TTntStrings }
+
+constructor TTntStrings.Create;
+begin
+ inherited;
+ FAnsiStrings := TAnsiStringsForWideStringsAdapter.Create(Self);
+ FLastFileCharSet := csUnicode;
+end;
+
+destructor TTntStrings.Destroy;
+begin
+ FreeAndNil(FAnsiStrings);
+ inherited;
+end;
+
+procedure TTntStrings.SetAnsiStrings(const Value: TAnsiStrings{TNT-ALLOW TAnsiStrings});
+begin
+ FAnsiStrings.Assign(Value);
+end;
+
+procedure TTntStrings.DefineProperties(Filer: TFiler);
+
+ {$IFNDEF COMPILER_7_UP}
+ function DoWrite: Boolean;
+ begin
+ if Filer.Ancestor <> nil then
+ begin
+ Result := True;
+ if Filer.Ancestor is TWideStrings then
+ Result := not Equals(TWideStrings(Filer.Ancestor))
+ end
+ else Result := Count > 0;
+ end;
+
+ function DoWriteAsUTF7: Boolean;
+ var
+ i: integer;
+ begin
+ Result := False;
+ for i := 0 to Count - 1 do begin
+ if (Strings[i] <> '') and (WideStringToUTF8(Strings[i]) <> Strings[i]) then begin
+ Result := True;
+ break; { found a string with non-ASCII chars (> 127) }
+ end;
+ end;
+ end;
+ {$ENDIF}
+
+begin
+ inherited DefineProperties(Filer); { Handles main 'Strings' property.' }
+ Filer.DefineProperty('WideStrings', ReadData, nil, False);
+ Filer.DefineProperty('WideStringsW', ReadDataUTF8, nil, False);
+ {$IFDEF COMPILER_7_UP}
+ Filer.DefineProperty('WideStrings_UTF7', ReadDataUTF7, WriteDataUTF7, False);
+ {$ELSE}
+ Filer.DefineProperty('WideStrings_UTF7', ReadDataUTF7, WriteDataUTF7, DoWrite and DoWriteAsUTF7);
+ {$ENDIF}
+end;
+
+procedure TTntStrings.LoadFromFile(const FileName: WideString);
+var
+ Stream: TStream;
+begin
+ Stream := TTntFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
+ try
+ FLastFileCharSet := AutoDetectCharacterSet(Stream);
+ Stream.Position := 0;
+ LoadFromStream(Stream);
+ finally
+ Stream.Free;
+ end;
+end;
+
+procedure TTntStrings.LoadFromStream(Stream: TStream);
+begin
+ LoadFromStream_BOM(Stream, True);
+end;
+
+procedure TTntStrings.LoadFromStream_BOM(Stream: TStream; WithBOM: Boolean);
+var
+ DataLeft: Integer;
+ StreamCharSet: TTntStreamCharSet;
+ SW: WideString;
+ SA: AnsiString;
+begin
+ BeginUpdate;
+ try
+ if WithBOM then
+ StreamCharSet := AutoDetectCharacterSet(Stream)
+ else
+ StreamCharSet := csUnicode;
+ DataLeft := Stream.Size - Stream.Position;
+ if (StreamCharSet in [csUnicode, csUnicodeSwapped]) then
+ begin
+ // BOM indicates Unicode text stream
+ if DataLeft < SizeOf(WideChar) then
+ SW := ''
+ else begin
+ SetLength(SW, DataLeft div SizeOf(WideChar));
+ Stream.Read(PWideChar(SW)^, DataLeft);
+ if StreamCharSet = csUnicodeSwapped then
+ StrSwapByteOrder(PWideChar(SW));
+ end;
+ SetTextStr(SW);
+ end
+ else if StreamCharSet = csUtf8 then
+ begin
+ // BOM indicates UTF-8 text stream
+ SetLength(SA, DataLeft div SizeOf(AnsiChar));
+ Stream.Read(PAnsiChar(SA)^, DataLeft);
+ SetTextStr(UTF8ToWideString(SA));
+ end
+ else
+ begin
+ // without byte order mark it is assumed that we are loading ANSI text
+ SetLength(SA, DataLeft div SizeOf(AnsiChar));
+ Stream.Read(PAnsiChar(SA)^, DataLeft);
+ SetTextStr(SA);
+ end;
+ finally
+ EndUpdate;
+ end;
+end;
+
+procedure TTntStrings.ReadData(Reader: TReader);
+begin
+ if Reader.NextValue in [vaString, vaLString] then
+ SetTextStr(Reader.ReadString) {JCL compatiblity}
+ else if Reader.NextValue = vaWString then
+ SetTextStr(Reader.ReadWideString) {JCL compatiblity}
+ else begin
+ BeginUpdate;
+ try
+ Clear;
+ Reader.ReadListBegin;
+ while not Reader.EndOfList do
+ if Reader.NextValue in [vaString, vaLString] then
+ Add(Reader.ReadString) {TStrings compatiblity}
+ else
+ Add(Reader.ReadWideString);
+ Reader.ReadListEnd;
+ finally
+ EndUpdate;
+ end;
+ end;
+end;
+
+procedure TTntStrings.ReadDataUTF7(Reader: TReader);
+begin
+ Reader.ReadListBegin;
+ if ReaderNeedsUtfHelp(Reader) then
+ begin
+ BeginUpdate;
+ try
+ Clear;
+ while not Reader.EndOfList do
+ Add(UTF7ToWideString(Reader.ReadString))
+ finally
+ EndUpdate;
+ end;
+ end else begin
+ while not Reader.EndOfList do
+ Reader.ReadString; { do nothing with Result }
+ end;
+ Reader.ReadListEnd;
+end;
+
+procedure TTntStrings.ReadDataUTF8(Reader: TReader);
+begin
+ Reader.ReadListBegin;
+ if ReaderNeedsUtfHelp(Reader)
+ or (Count = 0){ Legacy support where 'WideStrings' was never written in lieu of WideStringsW }
+ then begin
+ BeginUpdate;
+ try
+ Clear;
+ while not Reader.EndOfList do
+ Add(UTF8ToWideString(Reader.ReadString))
+ finally
+ EndUpdate;
+ end;
+ end else begin
+ while not Reader.EndOfList do
+ Reader.ReadString; { do nothing with Result }
+ end;
+ Reader.ReadListEnd;
+end;
+
+procedure TTntStrings.SaveToFile(const FileName: WideString);
+var
+ Stream: TStream;
+begin
+ Stream := TTntFileStream.Create(FileName, fmCreate);
+ try
+ SaveToStream(Stream);
+ finally
+ Stream.Free;
+ end;
+end;
+
+procedure TTntStrings.SaveToStream(Stream: TStream);
+begin
+ SaveToStream_BOM(Stream, True);
+end;
+
+procedure TTntStrings.SaveToStream_BOM(Stream: TStream; WithBOM: Boolean);
+// Saves the currently loaded text into the given stream.
+// WithBOM determines whether to write a byte order mark or not.
+var
+ SW: WideString;
+ BOM: WideChar;
+begin
+ if WithBOM then begin
+ BOM := UNICODE_BOM;
+ Stream.WriteBuffer(BOM, SizeOf(WideChar));
+ end;
+ SW := GetTextStr;
+ Stream.WriteBuffer(PWideChar(SW)^, Length(SW) * SizeOf(WideChar));
+end;
+
+procedure TTntStrings.WriteDataUTF7(Writer: TWriter);
+var
+ I: Integer;
+begin
+ Writer.WriteListBegin;
+ for I := 0 to Count-1 do
+ Writer.WriteString(WideStringToUTF7(Get(I)));
+ Writer.WriteListEnd;
+end;
+
+{ TTntStringList }
+
+destructor TTntStringList.Destroy;
+begin
+ FOnChange := nil;
+ FOnChanging := nil;
+ inherited Destroy;
+ if FCount <> 0 then Finalize(FList^[0], FCount);
+ FCount := 0;
+ SetCapacity(0);
+end;
+
+function TTntStringList.Add(const S: WideString): Integer;
+begin
+ Result := AddObject(S, nil);
+end;
+
+function TTntStringList.AddObject(const S: WideString; AObject: TObject): Integer;
+begin
+ if not Sorted then
+ Result := FCount
+ else
+ if Find(S, Result) then
+ case Duplicates of
+ dupIgnore: Exit;
+ dupError: Error(PResStringRec(@SDuplicateString), 0);
+ end;
+ InsertItem(Result, S, AObject);
+end;
+
+procedure TTntStringList.Changed;
+begin
+ if (not FUpdating) and Assigned(FOnChange) then
+ FOnChange(Self);
+end;
+
+procedure TTntStringList.Changing;
+begin
+ if (not FUpdating) and Assigned(FOnChanging) then
+ FOnChanging(Self);
+end;
+
+procedure TTntStringList.Clear;
+begin
+ if FCount <> 0 then
+ begin
+ Changing;
+ Finalize(FList^[0], FCount);
+ FCount := 0;
+ SetCapacity(0);
+ Changed;
+ end;
+end;
+
+procedure TTntStringList.Delete(Index: Integer);
+begin
+ if (Index < 0) or (Index >= FCount) then Error(PResStringRec(@SListIndexError), Index);
+ Changing;
+ Finalize(FList^[Index]);
+ Dec(FCount);
+ if Index < FCount then
+ System.Move(FList^[Index + 1], FList^[Index],
+ (FCount - Index) * SizeOf(TWideStringItem));
+ Changed;
+end;
+
+procedure TTntStringList.Exchange(Index1, Index2: Integer);
+begin
+ if (Index1 < 0) or (Index1 >= FCount) then Error(PResStringRec(@SListIndexError), Index1);
+ if (Index2 < 0) or (Index2 >= FCount) then Error(PResStringRec(@SListIndexError), Index2);
+ Changing;
+ ExchangeItems(Index1, Index2);
+ Changed;
+end;
+
+procedure TTntStringList.ExchangeItems(Index1, Index2: Integer);
+var
+ Temp: Integer;
+ Item1, Item2: PWideStringItem;
+begin
+ Item1 := @FList^[Index1];
+ Item2 := @FList^[Index2];
+ Temp := Integer(Item1^.FString);
+ Integer(Item1^.FString) := Integer(Item2^.FString);
+ Integer(Item2^.FString) := Temp;
+ Temp := Integer(Item1^.FObject);
+ Integer(Item1^.FObject) := Integer(Item2^.FObject);
+ Integer(Item2^.FObject) := Temp;
+end;
+
+function TTntStringList.Find(const S: WideString; var Index: Integer): Boolean;
+var
+ L, H, I, C: Integer;
+begin
+ Result := False;
+ L := 0;
+ H := FCount - 1;
+ while L <= H do
+ begin
+ I := (L + H) shr 1;
+ C := CompareStrings(FList^[I].FString, S);
+ if C < 0 then L := I + 1 else
+ begin
+ H := I - 1;
+ if C = 0 then
+ begin
+ Result := True;
+ if Duplicates <> dupAccept then L := I;
+ end;
+ end;
+ end;
+ Index := L;
+end;
+
+function TTntStringList.Get(Index: Integer): WideString;
+begin
+ if (Index < 0) or (Index >= FCount) then Error(PResStringRec(@SListIndexError), Index);
+ Result := FList^[Index].FString;
+end;
+
+function TTntStringList.GetCapacity: Integer;
+begin
+ Result := FCapacity;
+end;
+
+function TTntStringList.GetCount: Integer;
+begin
+ Result := FCount;
+end;
+
+function TTntStringList.GetObject(Index: Integer): TObject;
+begin
+ if (Index < 0) or (Index >= FCount) then Error(PResStringRec(@SListIndexError), Index);
+ Result := FList^[Index].FObject;
+end;
+
+procedure TTntStringList.Grow;
+var
+ Delta: Integer;
+begin
+ if FCapacity > 64 then Delta := FCapacity div 4 else
+ if FCapacity > 8 then Delta := 16 else
+ Delta := 4;
+ SetCapacity(FCapacity + Delta);
+end;
+
+function TTntStringList.IndexOf(const S: WideString): Integer;
+begin
+ if not Sorted then Result := inherited IndexOf(S) else
+ if not Find(S, Result) then Result := -1;
+end;
+
+function TTntStringList.IndexOfName(const Name: WideString): Integer;
+var
+ NameKey: WideString;
+begin
+ if not Sorted then
+ Result := inherited IndexOfName(Name)
+ else begin
+ // use sort to find index more quickly
+ NameKey := Name + NameValueSeparator;
+ Find(NameKey, Result);
+ if (Result < 0) or (Result > Count - 1) then
+ Result := -1
+ else if CompareStrings(NameKey, Copy(Strings[Result], 1, Length(NameKey))) <> 0 then
+ Result := -1
+ end;
+end;
+
+procedure TTntStringList.Insert(Index: Integer; const S: WideString);
+begin
+ InsertObject(Index, S, nil);
+end;
+
+procedure TTntStringList.InsertObject(Index: Integer; const S: WideString;
+ AObject: TObject);
+begin
+ if Sorted then Error(PResStringRec(@SSortedListError), 0);
+ if (Index < 0) or (Index > FCount) then Error(PResStringRec(@SListIndexError), Index);
+ InsertItem(Index, S, AObject);
+end;
+
+procedure TTntStringList.InsertItem(Index: Integer; const S: WideString; AObject: TObject);
+begin
+ Changing;
+ if FCount = FCapacity then Grow;
+ if Index < FCount then
+ System.Move(FList^[Index], FList^[Index + 1],
+ (FCount - Index) * SizeOf(TWideStringItem));
+ with FList^[Index] do
+ begin
+ Pointer(FString) := nil;
+ FObject := AObject;
+ FString := S;
+ end;
+ Inc(FCount);
+ Changed;
+end;
+
+procedure TTntStringList.Put(Index: Integer; const S: WideString);
+begin
+ if Sorted then Error(PResStringRec(@SSortedListError), 0);
+ if (Index < 0) or (Index >= FCount) then Error(PResStringRec(@SListIndexError), Index);
+ Changing;
+ FList^[Index].FString := S;
+ Changed;
+end;
+
+procedure TTntStringList.PutObject(Index: Integer; AObject: TObject);
+begin
+ if (Index < 0) or (Index >= FCount) then Error(PResStringRec(@SListIndexError), Index);
+ Changing;
+ FList^[Index].FObject := AObject;
+ Changed;
+end;
+
+procedure TTntStringList.QuickSort(L, R: Integer; SCompare: TWideStringListSortCompare);
+var
+ I, J, P: Integer;
+begin
+ repeat
+ I := L;
+ J := R;
+ P := (L + R) shr 1;
+ repeat
+ while SCompare(Self, I, P) < 0 do Inc(I);
+ while SCompare(Self, J, P) > 0 do Dec(J);
+ if I <= J then
+ begin
+ ExchangeItems(I, J);
+ if P = I then
+ P := J
+ else if P = J then
+ P := I;
+ Inc(I);
+ Dec(J);
+ end;
+ until I > J;
+ if L < J then QuickSort(L, J, SCompare);
+ L := I;
+ until I >= R;
+end;
+
+procedure TTntStringList.SetCapacity(NewCapacity: Integer);
+begin
+ ReallocMem(FList, NewCapacity * SizeOf(TWideStringItem));
+ FCapacity := NewCapacity;
+end;
+
+procedure TTntStringList.SetSorted(Value: Boolean);
+begin
+ if FSorted <> Value then
+ begin
+ if Value then Sort;
+ FSorted := Value;
+ end;
+end;
+
+procedure TTntStringList.SetUpdateState(Updating: Boolean);
+begin
+ FUpdating := Updating;
+ if Updating then Changing else Changed;
+end;
+
+function WideStringListCompareStrings(List: TTntStringList; Index1, Index2: Integer): Integer;
+begin
+ Result := List.CompareStrings(List.FList^[Index1].FString,
+ List.FList^[Index2].FString);
+end;
+
+procedure TTntStringList.Sort;
+begin
+ CustomSort(WideStringListCompareStrings);
+end;
+
+procedure TTntStringList.CustomSort(Compare: TWideStringListSortCompare);
+begin
+ if not Sorted and (FCount > 1) then
+ begin
+ Changing;
+ QuickSort(0, FCount - 1, Compare);
+ Changed;
+ end;
+end;
+
+function TTntStringList.CompareStrings(const S1, S2: WideString): Integer;
+begin
+ if CaseSensitive then
+ Result := WideCompareStr(S1, S2)
+ else
+ Result := WideCompareText(S1, S2);
+end;
+
+procedure TTntStringList.SetCaseSensitive(const Value: Boolean);
+begin
+ if Value <> FCaseSensitive then
+ begin
+ FCaseSensitive := Value;
+ if Sorted then Sort;
+ end;
+end;
+
+//------------------------- TntClasses introduced procs ----------------------------------
+
+function AutoDetectCharacterSet(Stream: TStream): TTntStreamCharSet;
+var
+ ByteOrderMark: WideChar;
+ BytesRead: Integer;
+ Utf8Test: array[0..2] of AnsiChar;
+begin
+ // Byte Order Mark
+ ByteOrderMark := #0;
+ if (Stream.Size - Stream.Position) >= SizeOf(ByteOrderMark) then begin
+ BytesRead := Stream.Read(ByteOrderMark, SizeOf(ByteOrderMark));
+ if (ByteOrderMark <> UNICODE_BOM) and (ByteOrderMark <> UNICODE_BOM_SWAPPED) then begin
+ ByteOrderMark := #0;
+ Stream.Seek(-BytesRead, soFromCurrent);
+ if (Stream.Size - Stream.Position) >= Length(Utf8Test) * SizeOf(AnsiChar) then begin
+ BytesRead := Stream.Read(Utf8Test[0], Length(Utf8Test) * SizeOf(AnsiChar));
+ if Utf8Test <> UTF8_BOM then
+ Stream.Seek(-BytesRead, soFromCurrent);
+ end;
+ end;
+ end;
+ // Test Byte Order Mark
+ if ByteOrderMark = UNICODE_BOM then
+ Result := csUnicode
+ else if ByteOrderMark = UNICODE_BOM_SWAPPED then
+ Result := csUnicodeSwapped
+ else if Utf8Test = UTF8_BOM then
+ Result := csUtf8
+ else
+ Result := csAnsi;
+end;
+
+function FindSortedListByTarget(List: TList; TargetCompare: TListTargetCompare;
+ Target: Pointer; var Index: Integer): Boolean;
+var
+ L, H, I, C: Integer;
+begin
+ Result := False;
+ L := 0;
+ H := List.Count - 1;
+ while L <= H do
+ begin
+ I := (L + H) shr 1;
+ C := TargetCompare(List[i], Target);
+ if C < 0 then L := I + 1 else
+ begin
+ H := I - 1;
+ if C = 0 then
+ begin
+ Result := True;
+ L := I;
+ end;
+ end;
+ end;
+ Index := L;
+end;
+
+function ClassIsRegistered(const clsid: TCLSID): Boolean;
+var
+ OleStr: POleStr;
+ Reg: TRegIniFile;
+ Key, Filename: WideString;
+begin
+ // First, check to see if there is a ProgID. This will tell if the
+ // control is registered on the machine. No ProgID, control won't run
+ Result := ProgIDFromCLSID(clsid, OleStr) = S_OK;
+ if not Result then Exit; //Bail as soon as anything goes wrong.
+
+ // Next, make sure that the file is actually there by rooting it out
+ // of the registry
+ Key := WideFormat('\SOFTWARE\Classes\CLSID\%s', [GUIDToString(clsid)]);
+ Reg := TRegIniFile.Create;
+ try
+ Reg.RootKey := HKEY_LOCAL_MACHINE;
+ Result := Reg.OpenKeyReadOnly(Key);
+ if not Result then Exit; // Bail as soon as anything goes wrong.
+
+ FileName := Reg.ReadString('InProcServer32', '', EmptyStr);
+ if (Filename = EmptyStr) then // try another key for the file name
+ begin
+ FileName := Reg.ReadString('InProcServer', '', EmptyStr);
+ end;
+ Result := Filename <> EmptyStr;
+ if not Result then Exit;
+ Result := WideFileExists(Filename);
+ finally
+ Reg.Free;
+ end;
+end;
+
+{ TBufferedAnsiString }
+
+procedure TBufferedAnsiString.Clear;
+begin
+ LastWriteIndex := 0;
+ if Length(FStringBuffer) > 0 then
+ FillChar(FStringBuffer[1], Length(FStringBuffer) * SizeOf(AnsiChar), 0);
+end;
+
+procedure TBufferedAnsiString.AddChar(const wc: AnsiChar);
+const
+ MIN_GROW_SIZE = 32;
+ MAX_GROW_SIZE = 256;
+var
+ GrowSize: Integer;
+begin
+ Inc(LastWriteIndex);
+ if LastWriteIndex > Length(FStringBuffer) then begin
+ GrowSize := Max(MIN_GROW_SIZE, Length(FStringBuffer));
+ GrowSize := Min(GrowSize, MAX_GROW_SIZE);
+ SetLength(FStringBuffer, Length(FStringBuffer) + GrowSize);
+ FillChar(FStringBuffer[LastWriteIndex], GrowSize * SizeOf(AnsiChar), 0);
+ end;
+ FStringBuffer[LastWriteIndex] := wc;
+end;
+
+procedure TBufferedAnsiString.AddString(const s: AnsiString);
+var
+ LenS: Integer;
+ BlockSize: Integer;
+ AllocSize: Integer;
+begin
+ LenS := Length(s);
+ if LenS > 0 then begin
+ Inc(LastWriteIndex);
+ if LastWriteIndex + LenS - 1 > Length(FStringBuffer) then begin
+ // determine optimum new allocation size
+ BlockSize := Length(FStringBuffer) div 2;
+ if BlockSize < 8 then
+ BlockSize := 8;
+ AllocSize := ((LenS div BlockSize) + 1) * BlockSize;
+ // realloc buffer
+ SetLength(FStringBuffer, Length(FStringBuffer) + AllocSize);
+ FillChar(FStringBuffer[Length(FStringBuffer) - AllocSize + 1], AllocSize * SizeOf(AnsiChar), 0);
+ end;
+ CopyMemory(@FStringBuffer[LastWriteIndex], @s[1], LenS * SizeOf(AnsiChar));
+ Inc(LastWriteIndex, LenS - 1);
+ end;
+end;
+
+procedure TBufferedAnsiString.AddBuffer(Buff: PAnsiChar; Chars: Integer);
+var
+ i: integer;
+begin
+ for i := 1 to Chars do begin
+ if Buff^ = #0 then
+ break;
+ AddChar(Buff^);
+ Inc(Buff);
+ end;
+end;
+
+function TBufferedAnsiString.Value: AnsiString;
+begin
+ Result := PAnsiChar(FStringBuffer);
+end;
+
+function TBufferedAnsiString.BuffPtr: PAnsiChar;
+begin
+ Result := PAnsiChar(FStringBuffer);
+end;
+
+{ TBufferedWideString }
+
+procedure TBufferedWideString.Clear;
+begin
+ LastWriteIndex := 0;
+ if Length(FStringBuffer) > 0 then
+ FillChar(FStringBuffer[1], Length(FStringBuffer) * SizeOf(WideChar), 0);
+end;
+
+procedure TBufferedWideString.AddChar(const wc: WideChar);
+const
+ MIN_GROW_SIZE = 32;
+ MAX_GROW_SIZE = 256;
+var
+ GrowSize: Integer;
+begin
+ Inc(LastWriteIndex);
+ if LastWriteIndex > Length(FStringBuffer) then begin
+ GrowSize := Max(MIN_GROW_SIZE, Length(FStringBuffer));
+ GrowSize := Min(GrowSize, MAX_GROW_SIZE);
+ SetLength(FStringBuffer, Length(FStringBuffer) + GrowSize);
+ FillChar(FStringBuffer[LastWriteIndex], GrowSize * SizeOf(WideChar), 0);
+ end;
+ FStringBuffer[LastWriteIndex] := wc;
+end;
+
+procedure TBufferedWideString.AddString(const s: WideString);
+var
+ i: integer;
+begin
+ for i := 1 to Length(s) do
+ AddChar(s[i]);
+end;
+
+procedure TBufferedWideString.AddBuffer(Buff: PWideChar; Chars: Integer);
+var
+ i: integer;
+begin
+ for i := 1 to Chars do begin
+ if Buff^ = #0 then
+ break;
+ AddChar(Buff^);
+ Inc(Buff);
+ end;
+end;
+
+function TBufferedWideString.Value: WideString;
+begin
+ Result := PWideChar(FStringBuffer);
+end;
+
+function TBufferedWideString.BuffPtr: PWideChar;
+begin
+ Result := PWideChar(FStringBuffer);
+end;
+
+{ TBufferedStreamReader }
+
+constructor TBufferedStreamReader.Create(Stream: TStream; BufferSize: Integer = 1024);
+begin
+ // init stream
+ FStream := Stream;
+ FStreamSize := Stream.Size;
+ // init buffer
+ FBufferSize := BufferSize;
+ SetLength(FBuffer, BufferSize);
+ FBufferStartPosition := -FBufferSize; { out of any useful range }
+ // init virtual position
+ FVirtualPosition := 0;
+end;
+
+function TBufferedStreamReader.Seek(Offset: Integer; Origin: Word): Longint;
+begin
+ case Origin of
+ soFromBeginning: FVirtualPosition := Offset;
+ soFromCurrent: Inc(FVirtualPosition, Offset);
+ soFromEnd: FVirtualPosition := FStreamSize + Offset;
+ end;
+ Result := FVirtualPosition;
+end;
+
+procedure TBufferedStreamReader.UpdateBufferFromPosition(StartPos: Integer);
+begin
+ try
+ FStream.Position := StartPos;
+ FStream.Read(FBuffer[0], FBufferSize);
+ FBufferStartPosition := StartPos;
+ except
+ FBufferStartPosition := -FBufferSize; { out of any useful range }
+ raise;
+ end;
+end;
+
+function TBufferedStreamReader.Read(var Buffer; Count: Integer): Longint;
+var
+ BytesLeft: Integer;
+ FirstBufferRead: Integer;
+ StreamDirectRead: Integer;
+ Buf: PAnsiChar;
+begin
+ if (FVirtualPosition >= 0) and (Count >= 0) then
+ begin
+ Result := FStreamSize - FVirtualPosition;
+ if Result > 0 then
+ begin
+ if Result > Count then
+ Result := Count;
+
+ Buf := @Buffer;
+ BytesLeft := Result;
+
+ // try to read what is left in buffer
+ FirstBufferRead := FBufferStartPosition + FBufferSize - FVirtualPosition;
+ if (FirstBufferRead < 0) or (FirstBufferRead > FBufferSize) then
+ FirstBufferRead := 0;
+ FirstBufferRead := Min(FirstBufferRead, Result);
+ if FirstBufferRead > 0 then begin
+ Move(FBuffer[FVirtualPosition - FBufferStartPosition], Buf[0], FirstBufferRead);
+ Dec(BytesLeft, FirstBufferRead);
+ end;
+
+ if BytesLeft > 0 then begin
+ // The first read in buffer was not enough
+ StreamDirectRead := (BytesLeft div FBufferSize) * FBufferSize;
+ FStream.Position := FVirtualPosition + FirstBufferRead;
+ FStream.Read(Buf[FirstBufferRead], StreamDirectRead);
+ Dec(BytesLeft, StreamDirectRead);
+
+ if BytesLeft > 0 then begin
+ // update buffer, and read what is left
+ UpdateBufferFromPosition(FStream.Position);
+ Move(FBuffer[0], Buf[FirstBufferRead + StreamDirectRead], BytesLeft);
+ end;
+ end;
+
+ Inc(FVirtualPosition, Result);
+ Exit;
+ end;
+ end;
+ Result := 0;
+end;
+
+function TBufferedStreamReader.Write(const Buffer; Count: Integer): Longint;
+begin
+ raise ETntInternalError.Create('Internal Error: class can not write.');
+ Result := 0;
+end;
+
+//-------- synced wide string -----------------
+
+function GetSyncedWideString(var WideStr: WideString; const AnsiStr: AnsiString): WideString;
+begin
+ if AnsiString(WideStr) <> (AnsiStr) then begin
+ WideStr := AnsiStr; {AnsiStr changed. Keep WideStr in sync.}
+ end;
+ Result := WideStr;
+end;
+
+procedure SetSyncedWideString(const Value: WideString; var WideStr: WideString;
+ const AnsiStr: AnsiString; SetAnsiStr: TSetAnsiStrEvent);
+begin
+ if Value <> GetSyncedWideString(WideStr, AnsiStr) then
+ begin
+ if (not WideSameStr(Value, AnsiString(Value))) {unicode chars lost in conversion}
+ and (AnsiStr = AnsiString(Value)) {AnsiStr is not going to change}
+ then begin
+ SetAnsiStr(''); {force the change}
+ end;
+ WideStr := Value;
+ SetAnsiStr(Value);
+ end;
+end;
+
+{ TWideComponentHelper }
+
+function CompareComponentHelperToTarget(Item, Target: Pointer): Integer;
+begin
+ if PtrUInt(TWideComponentHelper(Item).FComponent) < PtrUInt(Target) then
+ Result := -1
+ else if PtrUInt(TWideComponentHelper(Item).FComponent) > PtrUInt(Target) then
+ Result := 1
+ else
+ Result := 0;
+end;
+
+function FindWideComponentHelperIndex(ComponentHelperList: TComponentList; Component: TComponent; var Index: Integer): Boolean;
+begin
+ // find Component in sorted wide caption list (list is sorted by TWideComponentHelper.FComponent)
+ Result := FindSortedListByTarget(ComponentHelperList, CompareComponentHelperToTarget, Component, Index);
+end;
+
+constructor TWideComponentHelper.Create(AOwner: TComponent);
+begin
+ raise ETntInternalError.Create('TNT Internal Error: TWideComponentHelper.Create should never be encountered.');
+end;
+
+constructor TWideComponentHelper.CreateHelper(AOwner: TComponent; ComponentHelperList: TComponentList);
+var
+ Index: Integer;
+begin
+ // don't use direct ownership for memory management
+ inherited Create(nil);
+ FComponent := AOwner;
+ FComponent.FreeNotification(Self);
+
+ // insert into list according to sort
+ FindWideComponentHelperIndex(ComponentHelperList, FComponent, Index);
+ ComponentHelperList.Insert(Index, Self);
+end;
+
+procedure TWideComponentHelper.Notification(AComponent: TComponent; Operation: TOperation);
+begin
+ inherited;
+ if (AComponent = FComponent) and (Operation = opRemove) then begin
+ FComponent := nil;
+ Free;
+ end;
+end;
+
+function FindWideComponentHelper(ComponentHelperList: TComponentList; Component: TComponent): TWideComponentHelper;
+var
+ Index: integer;
+begin
+ if FindWideComponentHelperIndex(ComponentHelperList, Component, Index) then begin
+ Result := TWideComponentHelper(ComponentHelperList[Index]);
+ Assert(Result.FComponent = Component, 'TNT Internal Error: FindWideComponentHelperIndex failed.');
+ end else
+ Result := nil;
+end;
+
+initialization
+ RuntimeUTFStreaming := False; { Delphi 6 and higher don't need UTF help at runtime. }
+
+end.
diff --git a/cmake/src/lib/TntUnicodeControls/TntCompilers.inc b/cmake/src/lib/TntUnicodeControls/TntCompilers.inc new file mode 100644 index 00000000..90b51ef2 --- /dev/null +++ b/cmake/src/lib/TntUnicodeControls/TntCompilers.inc @@ -0,0 +1,378 @@ +//---------------------------------------------------------------------------------------------------------------------- +// Include file to determine which compiler is currently being used to build the project/component. +// This file uses ideas from Brad Stowers DFS.inc file (www.delphifreestuff.com). +// +// Portions created by Mike Lischke are Copyright +// (C) 1999-2002 Dipl. Ing. Mike Lischke. All Rights Reserved. +//---------------------------------------------------------------------------------------------------------------------- +// The following symbols are defined: +// +// COMPILER_1 : Kylix/Delphi/BCB 1.x is the compiler. +// COMPILER_1_UP : Kylix/Delphi/BCB 1.x or higher is the compiler. +// COMPILER_2 : Kylix/Delphi 2.x or BCB 1.x is the compiler. +// COMPILER_2_UP : Kylix/Delphi 2.x or higher, or BCB 1.x or higher is the compiler. +// COMPILER_3 : Kylix/Delphi/BCB 3.x is the compiler. +// COMPILER_3_UP : Kylix/Delphi/BCB 3.x or higher is the compiler. +// COMPILER_4 : Kylix/Delphi/BCB 4.x is the compiler. +// COMPILER_4_UP : Kylix/Delphi/BCB 4.x or higher is the compiler. +// COMPILER_5 : Kylix/Delphi/BCB 5.x is the compiler. +// COMPILER_5_UP : Kylix/Delphi/BCB 5.x or higher is the compiler. +// COMPILER_6 : Kylix/Delphi/BCB 6.x is the compiler. +// COMPILER_6_UP : Kylix/Delphi/BCB 6.x or higher is the compiler. +// COMPILER_7 : Kylix/Delphi/BCB 7.x is the compiler. +// COMPILER_7_UP : Kylix/Delphi/BCB 7.x or higher is the compiler. +// +// Only defined if Windows is the target: +// CPPB : Any version of BCB is being used. +// CPPB_1 : BCB v1.x is being used. +// CPPB_3 : BCB v3.x is being used. +// CPPB_3_UP : BCB v3.x or higher is being used. +// CPPB_4 : BCB v4.x is being used. +// CPPB_4_UP : BCB v4.x or higher is being used. +// CPPB_5 : BCB v5.x is being used. +// CPPB_5_UP : BCB v5.x or higher is being used. +// CPPB_6 : BCB v6.x is being used. +// CPPB_6_UP : BCB v6.x or higher is being used. +// +// Only defined if Windows is the target: +// DELPHI : Any version of Delphi is being used. +// DELPHI_1 : Delphi v1.x is being used. +// DELPHI_2 : Delphi v2.x is being used. +// DELPHI_2_UP : Delphi v2.x or higher is being used. +// DELPHI_3 : Delphi v3.x is being used. +// DELPHI_3_UP : Delphi v3.x or higher is being used. +// DELPHI_4 : Delphi v4.x is being used. +// DELPHI_4_UP : Delphi v4.x or higher is being used. +// DELPHI_5 : Delphi v5.x is being used. +// DELPHI_5_UP : Delphi v5.x or higher is being used. +// DELPHI_6 : Delphi v6.x is being used. +// DELPHI_6_UP : Delphi v6.x or higher is being used. +// DELPHI_7 : Delphi v7.x is being used. +// DELPHI_7_UP : Delphi v7.x or higher is being used. +// +// Only defined if Linux is the target: +// KYLIX : Any version of Kylix is being used. +// KYLIX_1 : Kylix 1.x is being used. +// KYLIX_1_UP : Kylix 1.x or higher is being used. +// KYLIX_2 : Kylix 2.x is being used. +// KYLIX_2_UP : Kylix 2.x or higher is being used. +// KYLIX_3 : Kylix 3.x is being used. +// KYLIX_3_UP : Kylix 3.x or higher is being used. +// +// Only defined if Linux is the target: +// QT_CLX : Trolltech's QT library is being used. +//---------------------------------------------------------------------------------------------------------------------- + +{$ifdef MSWINDOWS} + + {$ifdef VER180} + {$define COMPILER_10} + {$define DELPHI} + {$define DELPHI_10} + {$endif} + + {$ifdef VER170} + {$define COMPILER_9} + {$define DELPHI} + {$define DELPHI_9} + {$endif} + + {$ifdef VER150} + {$define COMPILER_7} + {$define DELPHI} + {$define DELPHI_7} + {$endif} + + {$ifdef VER140} + {$define COMPILER_6} + {$ifdef BCB} + {$define CPPB} + {$define CPPB_6} + {$else} + {$define DELPHI} + {$define DELPHI_6} + {$endif} + {$endif} + + {$ifdef VER130} + {$define COMPILER_5} + {$ifdef BCB} + {$define CPPB} + {$define CPPB_5} + {$else} + {$define DELPHI} + {$define DELPHI_5} + {$endif} + {$endif} + + {$ifdef VER125} + {$define COMPILER_4} + {$define CPPB} + {$define CPPB_4} + {$endif} + + {$ifdef VER120} + {$define COMPILER_4} + {$define DELPHI} + {$define DELPHI_4} + {$endif} + + {$ifdef VER110} + {$define COMPILER_3} + {$define CPPB} + {$define CPPB_3} + {$endif} + + {$ifdef VER100} + {$define COMPILER_3} + {$define DELPHI} + {$define DELPHI_3} + {$endif} + + {$ifdef VER93} + {$define COMPILER_2} // C++ Builder v1 compiler is really v2 + {$define CPPB} + {$define CPPB_1} + {$endif} + + {$ifdef VER90} + {$define COMPILER_2} + {$define DELPHI} + {$define DELPHI_2} + {$endif} + + {$ifdef VER80} + {$define COMPILER_1} + {$define DELPHI} + {$define DELPHI_1} + {$endif} + + {$ifdef FPC} + {.$define DELPHI} + {$endif} + + {$ifdef DELPHI_2} + {$define DELPHI_2_UP} + {$endif} + + {$ifdef DELPHI_3} + {$define DELPHI_2_UP} + {$define DELPHI_3_UP} + {$endif} + + {$ifdef DELPHI_4} + {$define DELPHI_2_UP} + {$define DELPHI_3_UP} + {$define DELPHI_4_UP} + {$endif} + + {$ifdef DELPHI_5} + {$define DELPHI_2_UP} + {$define DELPHI_3_UP} + {$define DELPHI_4_UP} + {$define DELPHI_5_UP} + {$endif} + + {$ifdef DELPHI_6} + {$define DELPHI_2_UP} + {$define DELPHI_3_UP} + {$define DELPHI_4_UP} + {$define DELPHI_5_UP} + {$define DELPHI_6_UP} + {$endif} + + {$ifdef DELPHI_7} + {$define DELPHI_2_UP} + {$define DELPHI_3_UP} + {$define DELPHI_4_UP} + {$define DELPHI_5_UP} + {$define DELPHI_6_UP} + {$define DELPHI_7_UP} + {$endif} + + {$ifdef DELPHI_9} + {$define DELPHI_2_UP} + {$define DELPHI_3_UP} + {$define DELPHI_4_UP} + {$define DELPHI_5_UP} + {$define DELPHI_6_UP} + {$define DELPHI_7_UP} + {$define DELPHI_9_UP} + {$endif} + + {$ifdef DELPHI_10} + {$define DELPHI_2_UP} + {$define DELPHI_3_UP} + {$define DELPHI_4_UP} + {$define DELPHI_5_UP} + {$define DELPHI_6_UP} + {$define DELPHI_7_UP} + {$define DELPHI_9_UP} + {$define DELPHI_10_UP} + {$endif} + + {$ifdef CPPB_3} + {$define CPPB_3_UP} + {$endif} + + {$ifdef CPPB_4} + {$define CPPB_3_UP} + {$define CPPB_4_UP} + {$endif} + + {$ifdef CPPB_5} + {$define CPPB_3_UP} + {$define CPPB_4_UP} + {$define CPPB_5_UP} + {$endif} + + {$ifdef CPPB_6} + {$define CPPB_3_UP} + {$define CPPB_4_UP} + {$define CPPB_5_UP} + {$define CPPB_6_UP} + {$endif} + + {$ifdef CPPB_3_UP} + // C++ Builder requires this if you use Delphi components in run-time packages. + {$ObjExportAll On} + {$endif} + +{$else (not Windows)} + // Linux is the target + {$define QT_CLX} + + {$define KYLIX} + {$define KYLIX_1} + {$define KYLIX_1_UP} + + {$ifdef VER150} + {$define COMPILER_7} + {$define KYLIX_3} + {$endif} + + {$ifdef VER140} + {$define COMPILER_6} + {$define KYLIX_2} + {$endif} + + {$ifdef KYLIX_2} + {$define KYLIX_2_UP} + {$endif} + + {$ifdef KYLIX_3} + {$define KYLIX_2_UP} + {$define KYLIX_3_UP} + {$endif} + +{$endif} + +// Compiler defines common to all platforms. +{$ifdef COMPILER_1} + {$define COMPILER_1_UP} +{$endif} + +{$ifdef COMPILER_2} + {$define COMPILER_1_UP} + {$define COMPILER_2_UP} +{$endif} + +{$ifdef COMPILER_3} + {$define COMPILER_1_UP} + {$define COMPILER_2_UP} + {$define COMPILER_3_UP} +{$endif} + +{$ifdef COMPILER_4} + {$define COMPILER_1_UP} + {$define COMPILER_2_UP} + {$define COMPILER_3_UP} + {$define COMPILER_4_UP} +{$endif} + +{$ifdef COMPILER_5} + {$define COMPILER_1_UP} + {$define COMPILER_2_UP} + {$define COMPILER_3_UP} + {$define COMPILER_4_UP} + {$define COMPILER_5_UP} +{$endif} + +{$ifdef COMPILER_6} + {$define COMPILER_1_UP} + {$define COMPILER_2_UP} + {$define COMPILER_3_UP} + {$define COMPILER_4_UP} + {$define COMPILER_5_UP} + {$define COMPILER_6_UP} +{$endif} + +{$ifdef COMPILER_7} + {$define COMPILER_1_UP} + {$define COMPILER_2_UP} + {$define COMPILER_3_UP} + {$define COMPILER_4_UP} + {$define COMPILER_5_UP} + {$define COMPILER_6_UP} + {$define COMPILER_7_UP} +{$endif} + +{$ifdef COMPILER_9} + {$define COMPILER_1_UP} + {$define COMPILER_2_UP} + {$define COMPILER_3_UP} + {$define COMPILER_4_UP} + {$define COMPILER_5_UP} + {$define COMPILER_6_UP} + {$define COMPILER_7_UP} + {$define COMPILER_9_UP} +{$endif} + +{$ifdef COMPILER_10} + {$define COMPILER_1_UP} + {$define COMPILER_2_UP} + {$define COMPILER_3_UP} + {$define COMPILER_4_UP} + {$define COMPILER_5_UP} + {$define COMPILER_6_UP} + {$define COMPILER_7_UP} + {$define COMPILER_9_UP} + {$define COMPILER_10_UP} +{$endif} + +//---------------------------------------------------------------------------------------------------------------------- + +{$ALIGN ON} +{$BOOLEVAL OFF} + +{$ifdef COMPILER_7_UP} + {$define THEME_7_UP} { Allows experimental theme support on pre-Delphi 7. } +{$endif} + +{$IFDEF COMPILER_6_UP} +{$WARN SYMBOL_PLATFORM OFF} { We are going to use Win32 specific symbols! } +{$ENDIF} + +{$IFDEF COMPILER_7_UP} +{$IFDEF FPC} + {$DEFINE UNSAFE_WARNINGS_OFF} +{$ENDIF} +{$ENDIF} + +{$IFDEF UNSAFE_WARNINGS_OFF} +{$WARN UNSAFE_CODE OFF} { We are not going to be "safe"! } +{$WARN UNSAFE_TYPE OFF} +{$WARN UNSAFE_CAST OFF} +{$ENDIF} + +{$IFDEF FPC} +{$HINTS OFF} +{$ENDIF} + +{$IFNDEF FPC} + // Delphi system function overrides might (not tested) cause problems on + // CPUs with code protection (NX-bit). So disable by default. + {.$DEFINE USE_SYSTEM_OVERRIDES} +{$ENDIF} + + diff --git a/cmake/src/lib/TntUnicodeControls/TntFormatStrUtils.pas b/cmake/src/lib/TntUnicodeControls/TntFormatStrUtils.pas new file mode 100644 index 00000000..80aefd4a --- /dev/null +++ b/cmake/src/lib/TntUnicodeControls/TntFormatStrUtils.pas @@ -0,0 +1,521 @@ +
+{*****************************************************************************}
+{ }
+{ Tnt Delphi Unicode Controls }
+{ http://www.tntware.com/delphicontrols/unicode/ }
+{ Version: 2.3.0 }
+{ }
+{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) }
+{ }
+{*****************************************************************************}
+
+unit TntFormatStrUtils;
+
+{$IFDEF FPC}
+ {$MODE Delphi}
+{$ENDIF}
+
+{$INCLUDE TntCompilers.inc}
+
+interface
+
+// this unit provides functions to work with format strings
+
+uses
+ TntSysUtils;
+
+function GetCanonicalFormatStr(const _FormatString: WideString): WideString;
+
+{$IFNDEF FPC}
+{$IFNDEF COMPILER_9_UP}
+function ReplaceFloatingArgumentsInFormatString(const _FormatString: WideString;
+ const Args: array of const
+ {$IFDEF COMPILER_7_UP}; FormatSettings: PFormatSettings{$ENDIF}): WideString;
+{$ENDIF}
+{$ENDIF}
+procedure CompareFormatStrings(FormatStr1, FormatStr2: WideString);
+function FormatStringsAreCompatible(FormatStr1, FormatStr2: WideString): Boolean;
+
+type
+ EFormatSpecError = class(ETntGeneralError);
+
+implementation
+
+uses
+ SysUtils, Math, TntClasses;
+
+resourcestring
+ SInvalidFormatSpecifier = 'Invalid Format Specifier: %s';
+ SMismatchedArgumentTypes = 'Argument types for index %d do not match. (%s <> %s)';
+ SMismatchedArgumentCounts = 'Number of format specifiers do not match.';
+
+type
+ TFormatSpecifierType = (fstInteger, fstFloating, fstPointer, fstString);
+
+function GetFormatSpecifierType(const FormatSpecifier: WideString): TFormatSpecifierType;
+var
+ LastChar: WideChar;
+begin
+ LastChar := TntWideLastChar(FormatSpecifier);
+ case LastChar of
+ 'd', 'D', 'u', 'U', 'x', 'X':
+ result := fstInteger;
+ 'e', 'E', 'f', 'F', 'g', 'G', 'n', 'N', 'm', 'M':
+ result := fstFloating;
+ 'p', 'P':
+ result := fstPointer;
+ 's', 'S':
+ result := fstString
+ else
+ raise ETntInternalError.CreateFmt('Internal Error: Unexpected format type (%s)', [LastChar]);
+ end;
+end;
+
+type
+ TFormatStrParser = class(TObject)
+ private
+ ParsedString: TBufferedWideString;
+ PFormatString: PWideChar;
+ LastIndex: Integer;
+ ExplicitCount: Integer;
+ ImplicitCount: Integer;
+ procedure RaiseInvalidFormatSpecifier;
+ function ParseChar(c: WideChar): Boolean;
+ procedure ForceParseChar(c: WideChar);
+ function ParseDigit: Boolean;
+ function ParseInteger: Boolean;
+ procedure ForceParseType;
+ function PeekDigit: Boolean;
+ function PeekIndexSpecifier(out Index: Integer): Boolean;
+ public
+ constructor Create(const _FormatString: WideString);
+ destructor Destroy; override;
+ function ParseFormatSpecifier: Boolean;
+ end;
+
+constructor TFormatStrParser.Create(const _FormatString: WideString);
+begin
+ inherited Create;
+ PFormatString := PWideChar(_FormatString);
+ ExplicitCount := 0;
+ ImplicitCount := 0;
+ LastIndex := -1;
+ ParsedString := TBufferedWideString.Create;
+end;
+
+destructor TFormatStrParser.Destroy;
+begin
+ FreeAndNil(ParsedString);
+ inherited;
+end;
+
+procedure TFormatStrParser.RaiseInvalidFormatSpecifier;
+begin
+ raise EFormatSpecError.CreateFmt(SInvalidFormatSpecifier, [ParsedString.Value + PFormatString]);
+end;
+
+function TFormatStrParser.ParseChar(c: WideChar): Boolean;
+begin
+ result := False;
+ if PFormatString^ = c then begin
+ result := True;
+ ParsedString.AddChar(c);
+ Inc(PFormatString);
+ end;
+end;
+
+procedure TFormatStrParser.ForceParseChar(c: WideChar);
+begin
+ if not ParseChar(c) then
+ RaiseInvalidFormatSpecifier;
+end;
+
+function TFormatStrParser.PeekDigit: Boolean;
+begin
+ result := False;
+ if (PFormatString^ <> #0)
+ and (PFormatString^ >= '0')
+ and (PFormatString^ <= '9') then
+ result := True;
+end;
+
+function TFormatStrParser.ParseDigit: Boolean;
+begin
+ result := False;
+ if PeekDigit then begin
+ result := True;
+ ForceParseChar(PFormatString^);
+ end;
+end;
+
+function TFormatStrParser.ParseInteger: Boolean;
+const
+ MAX_INT_DIGITS = 6;
+var
+ digitcount: integer;
+begin
+ digitcount := 0;
+ While ParseDigit do begin
+ inc(digitcount);
+ end;
+ result := (digitcount > 0);
+ if digitcount > MAX_INT_DIGITS then
+ RaiseInvalidFormatSpecifier;
+end;
+
+procedure TFormatStrParser.ForceParseType;
+begin
+ if PFormatString^ = #0 then
+ RaiseInvalidFormatSpecifier;
+
+ case PFormatString^ of
+ 'd', 'u', 'x', 'e', 'f', 'g', 'n', 'm', 'p', 's',
+ 'D', 'U', 'X', 'E', 'F', 'G', 'N', 'M', 'P', 'S':
+ begin
+ // do nothing
+ end
+ else
+ RaiseInvalidFormatSpecifier;
+ end;
+ ForceParseChar(PFormatString^);
+end;
+
+function TFormatStrParser.PeekIndexSpecifier(out Index: Integer): Boolean;
+var
+ SaveParsedString: WideString;
+ SaveFormatString: PWideChar;
+begin
+ SaveParsedString := ParsedString.Value;
+ SaveFormatString := PFormatString;
+ try
+ ParsedString.Clear;
+ Result := False;
+ Index := -1;
+ if ParseInteger then begin
+ Index := StrToInt(ParsedString.Value);
+ if ParseChar(':') then
+ Result := True;
+ end;
+ finally
+ ParsedString.Clear;
+ ParsedString.AddString(SaveParsedString);
+ PFormatString := SaveFormatString;
+ end;
+end;
+
+function TFormatStrParser.ParseFormatSpecifier: Boolean;
+var
+ ExplicitIndex: Integer;
+begin
+ Result := False;
+ // Parse entire format specifier
+ ForceParseChar('%');
+ if (PFormatString^ <> #0)
+ and (not ParseChar(' '))
+ and (not ParseChar('%')) then begin
+ if PeekIndexSpecifier(ExplicitIndex) then begin
+ Inc(ExplicitCount);
+ LastIndex := Max(LastIndex, ExplicitIndex);
+ end else begin
+ Inc(ImplicitCount);
+ Inc(LastIndex);
+ ParsedString.AddString(IntToStr(LastIndex));
+ ParsedString.AddChar(':');
+ end;
+ if ParseChar('*') then
+ begin
+ Inc(ImplicitCount);
+ Inc(LastIndex);
+ ParseChar(':');
+ end else if ParseInteger then
+ ParseChar(':');
+ ParseChar('-');
+ if ParseChar('*') then begin
+ Inc(ImplicitCount);
+ Inc(LastIndex);
+ end else
+ ParseInteger;
+ if ParseChar('.') then begin
+ if not ParseChar('*') then
+ ParseInteger;
+ end;
+ ForceParseType;
+ Result := True;
+ end;
+end;
+
+//-----------------------------------
+
+function GetCanonicalFormatStr(const _FormatString: WideString): WideString;
+var
+ PosSpec: Integer;
+begin
+ with TFormatStrParser.Create(_FormatString) do
+ try
+ // loop until no more '%'
+ PosSpec := Pos(WideString('%'), PFormatString);
+ While PosSpec <> 0 do begin
+ try
+ // delete everything up until '%'
+ ParsedString.AddBuffer(PFormatString, PosSpec - 1);
+ Inc(PFormatString, PosSpec - 1);
+ // parse format specifier
+ ParseFormatSpecifier;
+ finally
+ PosSpec := Pos(WideString('%'), PFormatString);
+ end;
+ end;
+ if ((ExplicitCount = 0) and (ImplicitCount = 1)) {simple expression}
+ or ((ExplicitCount > 0) and (ImplicitCount = 0)) {nothing converted} then
+ result := _FormatString {original}
+ else
+ result := ParsedString.Value + PFormatString;
+ finally
+ Free;
+ end;
+end;
+
+{$IFNDEF FPC}
+{$IFNDEF COMPILER_9_UP}
+function ReplaceFloatingArgumentsInFormatString(const _FormatString: WideString;
+ const Args: array of const
+ {$IFDEF COMPILER_7_UP}; FormatSettings: PFormatSettings{$ENDIF}): WideString;
+{ This function replaces floating point format specifiers with their actual formatted values.
+ It also adds index specifiers so that the other format specifiers don't lose their place.
+ The reason for this is that WideFormat doesn't correctly format floating point specifiers.
+ See QC#4254. }
+var
+ Parser: TFormatStrParser;
+ PosSpec: Integer;
+ Output: TBufferedWideString;
+begin
+ Output := TBufferedWideString.Create;
+ try
+ Parser := TFormatStrParser.Create(_FormatString);
+ with Parser do
+ try
+ // loop until no more '%'
+ PosSpec := Pos('%', PFormatString);
+ While PosSpec <> 0 do begin
+ try
+ // delete everything up until '%'
+ Output.AddBuffer(PFormatString, PosSpec - 1);
+ Inc(PFormatString, PosSpec - 1);
+ // parse format specifier
+ ParsedString.Clear;
+ if (not ParseFormatSpecifier)
+ or (GetFormatSpecifierType(ParsedString.Value) <> fstFloating) then
+ Output.AddBuffer(ParsedString.BuffPtr, MaxInt)
+ {$IFDEF COMPILER_7_UP}
+ else if Assigned(FormatSettings) then
+ Output.AddString(Format{TNT-ALLOW Format}(ParsedString.Value, Args, FormatSettings^))
+ {$ENDIF}
+ else
+ Output.AddString(Format{TNT-ALLOW Format}(ParsedString.Value, Args));
+ finally
+ PosSpec := Pos('%', PFormatString);
+ end;
+ end;
+ Output.AddString(PFormatString);
+ finally
+ Free;
+ end;
+ Result := Output.Value;
+ finally
+ Output.Free;
+ end;
+end;
+{$ENDIF}
+{$ENDIF}
+
+procedure GetFormatArgs(const _FormatString: WideString; FormatArgs: TTntStrings);
+var
+ PosSpec: Integer;
+begin
+ with TFormatStrParser.Create(_FormatString) do
+ try
+ FormatArgs.Clear;
+ // loop until no more '%'
+ PosSpec := Pos(WideString('%'), PFormatString);
+ While PosSpec <> 0 do begin
+ try
+ // delete everything up until '%'
+ Inc(PFormatString, PosSpec - 1);
+ // add format specifier to list
+ ParsedString.Clear;
+ if ParseFormatSpecifier then
+ FormatArgs.Add(ParsedString.Value);
+ finally
+ PosSpec := Pos(WideString('%'), PFormatString);
+ end;
+ end;
+ finally
+ Free;
+ end;
+end;
+
+function GetExplicitIndex(const FormatSpecifier: WideString): Integer;
+var
+ IndexStr: WideString;
+ PosColon: Integer;
+begin
+ result := -1;
+ PosColon := Pos(':', FormatSpecifier);
+ if PosColon <> 0 then begin
+ IndexStr := Copy(FormatSpecifier, 2, PosColon - 2);
+ result := StrToInt(IndexStr);
+ end;
+end;
+
+function GetMaxIndex(FormatArgs: TTntStrings): Integer;
+var
+ i: integer;
+ RunningIndex: Integer;
+ ExplicitIndex: Integer;
+begin
+ result := -1;
+ RunningIndex := -1;
+ for i := 0 to FormatArgs.Count - 1 do begin
+ ExplicitIndex := GetExplicitIndex(FormatArgs[i]);
+ if ExplicitIndex <> -1 then
+ RunningIndex := ExplicitIndex
+ else
+ inc(RunningIndex);
+ result := Max(result, RunningIndex);
+ end;
+end;
+
+function FormatSpecToObject(SpecType: TFormatSpecifierType): TObject;
+begin
+ {$IFNDEF FPC}
+ Result := TObject(SpecType);
+ {$ELSE}
+ Result := Pointer(SpecType);
+ {$ENDIF}
+end;
+
+procedure UpdateTypeList(FormatArgs, TypeList: TTntStrings);
+var
+ i: integer;
+ f: WideString;
+ SpecType: TFormatSpecifierType;
+ ExplicitIndex: Integer;
+ MaxIndex: Integer;
+ RunningIndex: Integer;
+begin
+ // set count of TypeList to accomodate maximum index
+ MaxIndex := GetMaxIndex(FormatArgs);
+ TypeList.Clear;
+ for i := 0 to MaxIndex do
+ TypeList.Add('');
+
+ // for each arg...
+ RunningIndex := -1;
+ for i := 0 to FormatArgs.Count - 1 do begin
+ f := FormatArgs[i];
+ ExplicitIndex := GetExplicitIndex(f);
+ SpecType := GetFormatSpecifierType(f);
+
+ // determine running arg index
+ if ExplicitIndex <> -1 then
+ RunningIndex := ExplicitIndex
+ else
+ inc(RunningIndex);
+
+ if TypeList[RunningIndex] <> '' then begin
+ // already exists in list, check for compatibility
+ if TypeList.Objects[RunningIndex] <> FormatSpecToObject(SpecType) then
+ raise EFormatSpecError.CreateFmt(SMismatchedArgumentTypes,
+ [RunningIndex, TypeList[RunningIndex], f]);
+ end else begin
+ // not in list so update it
+ TypeList[RunningIndex] := f;
+ TypeList.Objects[RunningIndex] := FormatSpecToObject(SpecType);
+ end;
+ end;
+end;
+
+procedure CompareFormatStrings(FormatStr1, FormatStr2: WideString);
+var
+ ArgList1: TTntStringList;
+ ArgList2: TTntStringList;
+ TypeList1: TTntStringList;
+ TypeList2: TTntStringList;
+ i: integer;
+begin
+ ArgList1 := nil;
+ ArgList2 := nil;
+ TypeList1 := nil;
+ TypeList2 := nil;
+ try
+ ArgList1 := TTntStringList.Create;
+ ArgList2 := TTntStringList.Create;
+ TypeList1 := TTntStringList.Create;
+ TypeList2 := TTntStringList.Create;
+
+ GetFormatArgs(FormatStr1, ArgList1);
+ UpdateTypeList(ArgList1, TypeList1);
+
+ GetFormatArgs(FormatStr2, ArgList2);
+ UpdateTypeList(ArgList2, TypeList2);
+
+ if TypeList1.Count <> TypeList2.Count then
+ raise EFormatSpecError.Create(SMismatchedArgumentCounts + CRLF + CRLF + '> ' + FormatStr1 + CRLF + '> ' + FormatStr2);
+
+ for i := 0 to TypeList1.Count - 1 do begin
+ if TypeList1.Objects[i] <> TypeList2.Objects[i] then begin
+ raise EFormatSpecError.CreateFmt(SMismatchedArgumentTypes,
+ [i, TypeList1[i], TypeList2[i]]);
+ end;
+ end;
+
+ finally
+ ArgList1.Free;
+ ArgList2.Free;
+ TypeList1.Free;
+ TypeList2.Free;
+ end;
+end;
+
+function FormatStringsAreCompatible(FormatStr1, FormatStr2: WideString): Boolean;
+var
+ ArgList1: TTntStringList;
+ ArgList2: TTntStringList;
+ TypeList1: TTntStringList;
+ TypeList2: TTntStringList;
+ i: integer;
+begin
+ ArgList1 := nil;
+ ArgList2 := nil;
+ TypeList1 := nil;
+ TypeList2 := nil;
+ try
+ ArgList1 := TTntStringList.Create;
+ ArgList2 := TTntStringList.Create;
+ TypeList1 := TTntStringList.Create;
+ TypeList2 := TTntStringList.Create;
+
+ GetFormatArgs(FormatStr1, ArgList1);
+ UpdateTypeList(ArgList1, TypeList1);
+
+ GetFormatArgs(FormatStr2, ArgList2);
+ UpdateTypeList(ArgList2, TypeList2);
+
+ Result := (TypeList1.Count = TypeList2.Count);
+ if Result then begin
+ for i := 0 to TypeList1.Count - 1 do begin
+ if TypeList1.Objects[i] <> TypeList2.Objects[i] then begin
+ Result := False;
+ break;
+ end;
+ end;
+ end;
+ finally
+ ArgList1.Free;
+ ArgList2.Free;
+ TypeList1.Free;
+ TypeList2.Free;
+ end;
+end;
+
+end.
diff --git a/cmake/src/lib/TntUnicodeControls/TntSysUtils.pas b/cmake/src/lib/TntUnicodeControls/TntSysUtils.pas new file mode 100644 index 00000000..b7cf2467 --- /dev/null +++ b/cmake/src/lib/TntUnicodeControls/TntSysUtils.pas @@ -0,0 +1,1753 @@ + +{*****************************************************************************} +{ } +{ Tnt Delphi Unicode Controls } +{ http://www.tntware.com/delphicontrols/unicode/ } +{ Version: 2.3.0 } +{ } +{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } +{ } +{*****************************************************************************} + +unit TntSysUtils; + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +{$INCLUDE TntCompilers.inc} + +interface + +{ TODO: Consider: more filename functions from SysUtils } +{ TODO: Consider: string functions from StrUtils. } + +uses + Types, SysUtils, Windows, TntWindows; + +//--------------------------------------------------------------------------------------------- +// Tnt - Types +//--------------------------------------------------------------------------------------------- + +// ......... introduced ......... +type + // The user of the application did something plainly wrong. + ETntUserError = class(Exception); + // A general error occured. (ie. file didn't exist, server didn't return data, etc.) + ETntGeneralError = class(Exception); + // Like Assert(). An error occured that should never have happened, send me a bug report now! + ETntInternalError = class(Exception); + +{$IFNDEF FPC} +type + PtrInt = LongInt; + PtrUInt = LongWord; +{$ENDIF} + +//--------------------------------------------------------------------------------------------- +// Tnt - SysUtils +//--------------------------------------------------------------------------------------------- + +// ......... SBCS and MBCS functions with WideString replacements in SysUtils.pas ......... + +{TNT-WARN CompareStr} {TNT-WARN AnsiCompareStr} +{TNT-WARN SameStr} {TNT-WARN AnsiSameStr} +{TNT-WARN SameText} {TNT-WARN AnsiSameText} +{TNT-WARN CompareText} {TNT-WARN AnsiCompareText} +{TNT-WARN UpperCase} {TNT-WARN AnsiUpperCase} +{TNT-WARN LowerCase} {TNT-WARN AnsiLowerCase} + +{TNT-WARN AnsiPos} { --> Pos() supports WideString. } +{TNT-WARN FmtStr} +{TNT-WARN Format} +{TNT-WARN FormatBuf} + +// ......... MBCS Byte Type Procs ......... + +{TNT-WARN ByteType} +{TNT-WARN StrByteType} +{TNT-WARN ByteToCharIndex} +{TNT-WARN ByteToCharLen} +{TNT-WARN CharToByteIndex} +{TNT-WARN CharToByteLen} + +// ........ null-terminated string functions ......... + +{TNT-WARN StrEnd} +{TNT-WARN StrLen} +{TNT-WARN StrLCopy} +{TNT-WARN StrCopy} +{TNT-WARN StrECopy} +{TNT-WARN StrPLCopy} +{TNT-WARN StrPCopy} +{TNT-WARN StrLComp} +{TNT-WARN AnsiStrLComp} +{TNT-WARN StrComp} +{TNT-WARN AnsiStrComp} +{TNT-WARN StrLIComp} +{TNT-WARN AnsiStrLIComp} +{TNT-WARN StrIComp} +{TNT-WARN AnsiStrIComp} +{TNT-WARN StrLower} +{TNT-WARN AnsiStrLower} +{TNT-WARN StrUpper} +{TNT-WARN AnsiStrUpper} +{TNT-WARN StrPos} +{TNT-WARN AnsiStrPos} +{TNT-WARN StrScan} +{TNT-WARN AnsiStrScan} +{TNT-WARN StrRScan} +{TNT-WARN AnsiStrRScan} +{TNT-WARN StrLCat} +{TNT-WARN StrCat} +{TNT-WARN StrMove} +{TNT-WARN StrPas} +{TNT-WARN StrAlloc} +{TNT-WARN StrBufSize} +{TNT-WARN StrNew} +{TNT-WARN StrDispose} + +{TNT-WARN AnsiExtractQuotedStr} +{TNT-WARN AnsiLastChar} +{TNT-WARN AnsiStrLastChar} +{TNT-WARN QuotedStr} +{TNT-WARN AnsiQuotedStr} +{TNT-WARN AnsiDequotedStr} + +// ........ string functions ......... + +{$IFNDEF FPC} +{$IFNDEF COMPILER_9_UP} + // + // pre-Delphi 9 issues w/ WideFormatBuf, WideFmtStr and WideFormat + // + + {$IFDEF COMPILER_7_UP} + type + PFormatSettings = ^TFormatSettings; + {$ENDIF} + + // SysUtils.WideFormatBuf doesn't correctly handle numeric specifiers. + function Tnt_WideFormatBuf(var Buffer; BufLen: Cardinal; const FormatStr; + FmtLen: Cardinal; const Args: array of const): Cardinal; {$IFDEF COMPILER_7_UP} overload; {$ENDIF} + + {$IFDEF COMPILER_7_UP} + function Tnt_WideFormatBuf(var Buffer; BufLen: Cardinal; const FormatStr; + FmtLen: Cardinal; const Args: array of const; + const FormatSettings: TFormatSettings): Cardinal; overload; + {$ENDIF} + + // SysUtils.WideFmtStr doesn't handle string lengths > 4096. + procedure Tnt_WideFmtStr(var Result: WideString; const FormatStr: WideString; + const Args: array of const); {$IFDEF COMPILER_7_UP} overload; {$ENDIF} + + {$IFDEF COMPILER_7_UP} + procedure Tnt_WideFmtStr(var Result: WideString; const FormatStr: WideString; + const Args: array of const; const FormatSettings: TFormatSettings); overload; + {$ENDIF} + + {---------------------------------------------------------------------------------------- + Without the FormatSettings parameter, Tnt_WideFormat is *NOT* necessary... + TntSystem.InstallTntSystemUpdates([tsFixWideFormat]); + will fix WideFormat as well as WideFmtStr. + ----------------------------------------------------------------------------------------} + function Tnt_WideFormat(const FormatStr: WideString; const Args: array of const): WideString; {$IFDEF COMPILER_7_UP} overload; {$ENDIF} + + {$IFDEF COMPILER_7_UP} + function Tnt_WideFormat(const FormatStr: WideString; const Args: array of const; + const FormatSettings: TFormatSettings): WideString; overload; + {$ENDIF} + +{$ENDIF} +{$ENDIF} + +{TNT-WARN WideUpperCase} // SysUtils.WideUpperCase is broken on Win9x for D6, D7, D9. +function Tnt_WideUpperCase(const S: WideString): WideString; +{TNT-WARN WideLowerCase} // SysUtils.WideLowerCase is broken on Win9x for D6, D7, D9. +function Tnt_WideLowerCase(const S: WideString): WideString; + +function TntWideLastChar(const S: WideString): WideChar; + +{TNT-WARN StringReplace} +{TNT-WARN WideStringReplace} // <-- WideStrUtils.WideStringReplace uses SysUtils.WideUpperCase which is broken on Win9x. +function Tnt_WideStringReplace(const S, OldPattern, NewPattern: WideString; + Flags: TReplaceFlags; WholeWord: Boolean = False): WideString; + +{TNT-WARN AdjustLineBreaks} +type TTntTextLineBreakStyle = (tlbsLF, tlbsCRLF, tlbsCR); +function TntAdjustLineBreaksLength(const S: WideString; Style: TTntTextLineBreakStyle = tlbsCRLF): Integer; +function TntAdjustLineBreaks(const S: WideString; Style: TTntTextLineBreakStyle = tlbsCRLF): WideString; + +{TNT-WARN WrapText} +function WideWrapText(const Line, BreakStr: WideString; const BreakChars: TSysCharSet; + MaxCol: Integer): WideString; overload; +function WideWrapText(const Line: WideString; MaxCol: Integer): WideString; overload; + +// ........ filename manipulation ......... + +{TNT-WARN SameFileName} // doesn't apply to Unicode filenames, use WideSameText +{TNT-WARN AnsiCompareFileName} // doesn't apply to Unicode filenames, use WideCompareText +{TNT-WARN AnsiLowerCaseFileName} // doesn't apply to Unicode filenames, use WideLowerCase +{TNT-WARN AnsiUpperCaseFileName} // doesn't apply to Unicode filenames, use WideUpperCase + +{TNT-WARN IncludeTrailingBackslash} +function WideIncludeTrailingBackslash(const S: WideString): WideString; +{TNT-WARN IncludeTrailingPathDelimiter} +function WideIncludeTrailingPathDelimiter(const S: WideString): WideString; +{TNT-WARN ExcludeTrailingBackslash} +function WideExcludeTrailingBackslash(const S: WideString): WideString; +{TNT-WARN ExcludeTrailingPathDelimiter} +function WideExcludeTrailingPathDelimiter(const S: WideString): WideString; +{TNT-WARN IsDelimiter} +function WideIsDelimiter(const Delimiters, S: WideString; Index: Integer): Boolean; +{TNT-WARN IsPathDelimiter} +function WideIsPathDelimiter(const S: WideString; Index: Integer): Boolean; +{TNT-WARN LastDelimiter} +function WideLastDelimiter(const Delimiters, S: WideString): Integer; +{TNT-WARN ChangeFileExt} +function WideChangeFileExt(const FileName, Extension: WideString): WideString; +{TNT-WARN ExtractFilePath} +function WideExtractFilePath(const FileName: WideString): WideString; +{TNT-WARN ExtractFileDir} +function WideExtractFileDir(const FileName: WideString): WideString; +{TNT-WARN ExtractFileDrive} +function WideExtractFileDrive(const FileName: WideString): WideString; +{TNT-WARN ExtractFileName} +function WideExtractFileName(const FileName: WideString): WideString; +{TNT-WARN ExtractFileExt} +function WideExtractFileExt(const FileName: WideString): WideString; +{TNT-WARN ExtractRelativePath} +function WideExtractRelativePath(const BaseName, DestName: WideString): WideString; + +// ........ file management routines ......... + +{TNT-WARN ExpandFileName} +function WideExpandFileName(const FileName: WideString): WideString; +{TNT-WARN ExtractShortPathName} +function WideExtractShortPathName(const FileName: WideString): WideString; +{TNT-WARN FileCreate} +function WideFileCreate(const FileName: WideString): Integer; +{TNT-WARN FileOpen} +function WideFileOpen(const FileName: WideString; Mode: LongWord): Integer; +{TNT-WARN FileAge} +function WideFileAge(const FileName: WideString): Integer; overload; +function WideFileAge(const FileName: WideString; out FileDateTime: TDateTime): Boolean; overload; +{TNT-WARN DirectoryExists} +function WideDirectoryExists(const Name: WideString): Boolean; +{TNT-WARN FileExists} +function WideFileExists(const Name: WideString): Boolean; +{TNT-WARN FileGetAttr} +function WideFileGetAttr(const FileName: WideString): Cardinal; +{TNT-WARN FileSetAttr} +function WideFileSetAttr(const FileName: WideString; Attr: Integer): Boolean; +{TNT-WARN FileIsReadOnly} +function WideFileIsReadOnly(const FileName: WideString): Boolean; +{TNT-WARN FileSetReadOnly} +function WideFileSetReadOnly(const FileName: WideString; ReadOnly: Boolean): Boolean; +{TNT-WARN ForceDirectories} +function WideForceDirectories(Dir: WideString): Boolean; +{TNT-WARN FileSearch} +function WideFileSearch(const Name, DirList: WideString): WideString; +{TNT-WARN RenameFile} +function WideRenameFile(const OldName, NewName: WideString): Boolean; +{TNT-WARN DeleteFile} +function WideDeleteFile(const FileName: WideString): Boolean; +{TNT-WARN CopyFile} +function WideCopyFile(const FromFile, ToFile: WideString; FailIfExists: Boolean): Boolean; + + +{TNT-WARN TFileName} +type + TWideFileName = type WideString; + +{TNT-WARN TSearchRec} // <-- FindFile - warning on TSearchRec is all that is necessary +type + TSearchRecW = record + Time: Integer; + Size: Int64; + Attr: Integer; + Name: TWideFileName; + ExcludeAttr: Integer; + FindHandle: THandle; + FindData: TWin32FindDataW; + end; +function WideFindFirst(const Path: WideString; Attr: Integer; var F: TSearchRecW): Integer; +function WideFindNext(var F: TSearchRecW): Integer; +procedure WideFindClose(var F: TSearchRecW); + +{TNT-WARN CreateDir} +function WideCreateDir(const Dir: WideString): Boolean; +{TNT-WARN RemoveDir} +function WideRemoveDir(const Dir: WideString): Boolean; +{TNT-WARN GetCurrentDir} +function WideGetCurrentDir: WideString; +{TNT-WARN SetCurrentDir} +function WideSetCurrentDir(const Dir: WideString): Boolean; + + +// ........ date/time functions ......... + +{TNT-WARN TryStrToDateTime} +function TntTryStrToDateTime(Str: WideString; out DateTime: TDateTime): Boolean; +{TNT-WARN TryStrToDate} +function TntTryStrToDate(Str: WideString; out DateTime: TDateTime): Boolean; +{TNT-WARN TryStrToTime} +function TntTryStrToTime(Str: WideString; out DateTime: TDateTime): Boolean; + +{ introduced } +function ValidDateTimeStr(Str: WideString): Boolean; +function ValidDateStr(Str: WideString): Boolean; +function ValidTimeStr(Str: WideString): Boolean; + +{TNT-WARN StrToDateTime} +function TntStrToDateTime(Str: WideString): TDateTime; +{TNT-WARN StrToDate} +function TntStrToDate(Str: WideString): TDateTime; +{TNT-WARN StrToTime} +function TntStrToTime(Str: WideString): TDateTime; +{TNT-WARN StrToDateTimeDef} +function TntStrToDateTimeDef(Str: WideString; Default: TDateTime): TDateTime; +{TNT-WARN StrToDateDef} +function TntStrToDateDef(Str: WideString; Default: TDateTime): TDateTime; +{TNT-WARN StrToTimeDef} +function TntStrToTimeDef(Str: WideString; Default: TDateTime): TDateTime; + +{TNT-WARN CurrToStr} +{TNT-WARN CurrToStrF} +function TntCurrToStr(Value: Currency; lpFormat: PCurrencyFmtW = nil): WideString; +{TNT-WARN StrToCurr} +function TntStrToCurr(const S: WideString): Currency; +{TNT-WARN StrToCurrDef} +function ValidCurrencyStr(const S: WideString): Boolean; +function TntStrToCurrDef(const S: WideString; const Default: Currency): Currency; +function GetDefaultCurrencyFmt: TCurrencyFmtW; + +// ........ misc functions ......... + +{TNT-WARN GetLocaleStr} +function WideGetLocaleStr(LocaleID: LCID; LocaleType: Integer; const Default: WideString): WideString; +{TNT-WARN SysErrorMessage} +function WideSysErrorMessage(ErrorCode: Integer): WideString; + +// ......... introduced ......... + +function WideLibraryErrorMessage(const LibName: WideString; Dll: THandle; ErrorCode: Integer): WideString; + +const + CR = WideChar(#13); + LF = WideChar(#10); + CRLF = WideString(#13#10); + WideLineSeparator = WideChar($2028); + +var + Win32PlatformIsUnicode: Boolean; + Win32PlatformIsXP: Boolean; + Win32PlatformIs2003: Boolean; + Win32PlatformIsVista: Boolean; + +{$IFNDEF FPC} +{$IFNDEF COMPILER_7_UP} +function CheckWin32Version(AMajor: Integer; AMinor: Integer = 0): Boolean; +{$ENDIF} +{$ENDIF} +function WinCheckH(RetVal: Cardinal): Cardinal; +function WinCheckFileH(RetVal: Cardinal): Cardinal; +function WinCheckP(RetVal: Pointer): Pointer; + +function WideGetModuleFileName(Instance: HModule): WideString; +function WideSafeLoadLibrary(const Filename: Widestring; + ErrorMode: UINT = SEM_NOOPENFILEERRORBOX): HMODULE; +{$IFNDEF FPC} +function WideLoadPackage(const Name: Widestring): HMODULE; +{$ENDIF} + +function IsWideCharUpper(WC: WideChar): Boolean; +function IsWideCharLower(WC: WideChar): Boolean; +function IsWideCharDigit(WC: WideChar): Boolean; +function IsWideCharSpace(WC: WideChar): Boolean; +function IsWideCharPunct(WC: WideChar): Boolean; +function IsWideCharCntrl(WC: WideChar): Boolean; +function IsWideCharBlank(WC: WideChar): Boolean; +function IsWideCharXDigit(WC: WideChar): Boolean; +function IsWideCharAlpha(WC: WideChar): Boolean; +function IsWideCharAlphaNumeric(WC: WideChar): Boolean; + +function WideTextPos(const SubStr, S: WideString): Integer; + +function ExtractStringArrayStr(P: PWideChar): WideString; +function ExtractStringFromStringArray(var P: PWideChar; Separator: WideChar = #0): WideString; +function ExtractStringsFromStringArray(P: PWideChar; Separator: WideChar = #0): TWideStringDynArray; + +function IsWideCharMappableToAnsi(const WC: WideChar): Boolean; +function IsWideStringMappableToAnsi(const WS: WideString): Boolean; +function IsRTF(const Value: WideString): Boolean; + +function ENG_US_FloatToStr(Value: Extended): WideString; +function ENG_US_StrToFloat(const S: WideString): Extended; + +//--------------------------------------------------------------------------------------------- +// Tnt - Variants +//--------------------------------------------------------------------------------------------- + +// ........ Variants.pas has WideString versions of these functions ......... +{TNT-WARN VarToStr} +{TNT-WARN VarToStrDef} + +var + _SettingChangeTime: Cardinal; + +implementation + +uses + ActiveX, ComObj, SysConst, + {$IFDEF COMPILER_9_UP} WideStrUtils, {$ENDIF} TntWideStrUtils, + TntSystem, TntFormatStrUtils; + +//--------------------------------------------------------------------------------------------- +// Tnt - SysUtils +//--------------------------------------------------------------------------------------------- + +{$IFNDEF FPC} +{$IFNDEF COMPILER_9_UP} + + function _Tnt_WideFormatBuf(var Buffer; BufLen: Cardinal; const FormatStr; + FmtLen: Cardinal; const Args: array of const + {$IFDEF COMPILER_7_UP}; const FormatSettings: PFormatSettings {$ENDIF}): Cardinal; + var + OldFormat: WideString; + NewFormat: WideString; + begin + SetString(OldFormat, PWideChar(@FormatStr), FmtLen); + { The reason for this is that WideFormat doesn't correctly format floating point specifiers. + See QC#4254. } + NewFormat := ReplaceFloatingArgumentsInFormatString(OldFormat, Args{$IFDEF COMPILER_7_UP}, FormatSettings{$ENDIF}); + {$IFDEF COMPILER_7_UP} + if FormatSettings <> nil then + Result := WideFormatBuf(Buffer, BufLen, Pointer(NewFormat)^, + Length(NewFormat), Args, FormatSettings^) + else + {$ENDIF} + Result := WideFormatBuf(Buffer, BufLen, Pointer(NewFormat)^, + Length(NewFormat), Args); + end; + + function Tnt_WideFormatBuf(var Buffer; BufLen: Cardinal; const FormatStr; + FmtLen: Cardinal; const Args: array of const): Cardinal; + begin + Result := _Tnt_WideFormatBuf(Buffer, BufLen, FormatStr, FmtLen, Args{$IFDEF COMPILER_7_UP}, nil{$ENDIF}); + end; + + {$IFDEF COMPILER_7_UP} + function Tnt_WideFormatBuf(var Buffer; BufLen: Cardinal; const FormatStr; + FmtLen: Cardinal; const Args: array of const; const FormatSettings: TFormatSettings): Cardinal; + begin + Result := _Tnt_WideFormatBuf(Buffer, BufLen, FormatStr, FmtLen, Args, @FormatSettings); + end; + {$ENDIF} + + procedure _Tnt_WideFmtStr(var Result: WideString; const FormatStr: WideString; + const Args: array of const{$IFDEF COMPILER_7_UP}; const FormatSettings: PFormatSettings{$ENDIF}); + var + Len, BufLen: Integer; + Buffer: array[0..4095] of WideChar; + begin + BufLen := Length(Buffer); // Fixes buffer overwrite issue. (See QC #4703, #4744) + if Length(FormatStr) < (Length(Buffer) - (Length(Buffer) div 4)) then + Len := _Tnt_WideFormatBuf(Buffer, Length(Buffer) - 1, Pointer(FormatStr)^, + Length(FormatStr), Args{$IFDEF COMPILER_7_UP}, FormatSettings{$ENDIF}) + else + begin + BufLen := Length(FormatStr); + Len := BufLen; + end; + if Len >= BufLen - 1 then + begin + while Len >= BufLen - 1 do + begin + Inc(BufLen, BufLen); + Result := ''; // prevent copying of existing data, for speed + SetLength(Result, BufLen); + Len := _Tnt_WideFormatBuf(Pointer(Result)^, BufLen - 1, Pointer(FormatStr)^, + Length(FormatStr), Args{$IFDEF COMPILER_7_UP}, FormatSettings{$ENDIF}); + end; + SetLength(Result, Len); + end + else + SetString(Result, Buffer, Len); + end; + + procedure Tnt_WideFmtStr(var Result: WideString; const FormatStr: WideString; + const Args: array of const); + begin + _Tnt_WideFmtStr(Result, FormatStr, Args{$IFDEF COMPILER_7_UP}, nil{$ENDIF}); + end; + + {$IFDEF COMPILER_7_UP} + procedure Tnt_WideFmtStr(var Result: WideString; const FormatStr: WideString; + const Args: array of const; const FormatSettings: TFormatSettings); + begin + _Tnt_WideFmtStr(Result, FormatStr, Args, @FormatSettings); + end; + {$ENDIF} + + {---------------------------------------------------------------------------------------- + Without the FormatSettings parameter, Tnt_WideFormat is *NOT* necessary... + TntSystem.InstallTntSystemUpdates([tsFixWideFormat]); + will fix WideFormat as well as WideFmtStr. + ----------------------------------------------------------------------------------------} + function Tnt_WideFormat(const FormatStr: WideString; const Args: array of const): WideString; + begin + Tnt_WideFmtStr(Result, FormatStr, Args); + end; + + {$IFDEF COMPILER_7_UP} + function Tnt_WideFormat(const FormatStr: WideString; const Args: array of const; + const FormatSettings: TFormatSettings): WideString; + begin + Tnt_WideFmtStr(Result, FormatStr, Args, FormatSettings); + end; + {$ENDIF} + +{$ENDIF} +{$ENDIF FPC} + +function Tnt_WideUpperCase(const S: WideString): WideString; +begin + {$IFNDEF FPC} + {$IFNDEF COMPILER_10_UP} + {$DEFINE WIDEUPPERCASE_BROKEN} + {$ENDIF} + {$ENDIF} + {$IFDEF WIDEUPPERCASE_BROKEN} + { SysUtils.WideUpperCase is broken for Win9x. } + Result := S; + if Length(Result) > 0 then + Tnt_CharUpperBuffW(PWideChar(Result), Length(Result)); + {$ELSE} + Result := SysUtils.WideUpperCase{TNT-ALLOW WideUpperCase}(S); + {$ENDIF} +end; + +function Tnt_WideLowerCase(const S: WideString): WideString; +begin + {$IFNDEF FPC} + {$IFNDEF COMPILER_10_UP} + {$DEFINE WIDELOWERCASE_BROKEN} + {$ENDIF} + {$ENDIF} + {$IFDEF WIDELOWERCASE_BROKEN} + { SysUtils.WideLowerCase is broken for Win9x. } + Result := S; + if Length(Result) > 0 then + Tnt_CharLowerBuffW(PWideChar(Result), Length(Result)); + {$ELSE} + Result := SysUtils.WideLowerCase{TNT-ALLOW WideLowerCase}(S); + {$ENDIF} +end; + +function TntWideLastChar(const S: WideString): WideChar; +var + P: PWideChar; +begin + P := WideLastChar(S); + if P = nil then + Result := #0 + else + Result := P^; +end; + +function Tnt_WideStringReplace(const S, OldPattern, NewPattern: WideString; + Flags: TReplaceFlags; WholeWord: Boolean = False): WideString; + + function IsWordSeparator(WC: WideChar): Boolean; + begin + Result := (WC = WideChar(#0)) + or IsWideCharSpace(WC) + or IsWideCharPunct(WC); + end; + +var + SearchStr, Patt, NewStr: WideString; + Offset: Integer; + PrevChar, NextChar: WideChar; +begin + if rfIgnoreCase in Flags then + begin + SearchStr := Tnt_WideUpperCase(S); + Patt := Tnt_WideUpperCase(OldPattern); + end else + begin + SearchStr := S; + Patt := OldPattern; + end; + NewStr := S; + Result := ''; + while SearchStr <> '' do + begin + Offset := Pos(Patt, SearchStr); + if Offset = 0 then + begin + Result := Result + NewStr; + Break; + end; // done + + if (WholeWord) then + begin + if (Offset = 1) then + PrevChar := TntWideLastChar(Result) + else + PrevChar := NewStr[Offset - 1]; + + if Offset + Length(OldPattern) <= Length(NewStr) then + NextChar := NewStr[Offset + Length(OldPattern)] + else + NextChar := WideChar(#0); + + if (not IsWordSeparator(PrevChar)) + or (not IsWordSeparator(NextChar)) then + begin + Result := Result + Copy(NewStr, 1, Offset + Length(OldPattern) - 1); + NewStr := Copy(NewStr, Offset + Length(OldPattern), MaxInt); + SearchStr := Copy(SearchStr, Offset + Length(Patt), MaxInt); + continue; + end; + end; + + Result := Result + Copy(NewStr, 1, Offset - 1) + NewPattern; + NewStr := Copy(NewStr, Offset + Length(OldPattern), MaxInt); + if not (rfReplaceAll in Flags) then + begin + Result := Result + NewStr; + Break; + end; + SearchStr := Copy(SearchStr, Offset + Length(Patt), MaxInt); + end; +end; + +function TntAdjustLineBreaksLength(const S: WideString; Style: TTntTextLineBreakStyle = tlbsCRLF): Integer; +var + Source, SourceEnd: PWideChar; +begin + Source := Pointer(S); + SourceEnd := Source + Length(S); + Result := Length(S); + while Source < SourceEnd do + begin + case Source^ of + #10, WideLineSeparator: + if Style = tlbsCRLF then + Inc(Result); + #13: + if Style = tlbsCRLF then + if Source[1] = #10 then + Inc(Source) + else + Inc(Result) + else + if Source[1] = #10 then + Dec(Result); + end; + Inc(Source); + end; +end; + +function TntAdjustLineBreaks(const S: WideString; Style: TTntTextLineBreakStyle = tlbsCRLF): WideString; +var + Source, SourceEnd, Dest: PWideChar; + DestLen: Integer; +begin + Source := Pointer(S); + SourceEnd := Source + Length(S); + DestLen := TntAdjustLineBreaksLength(S, Style); + SetString(Result, nil, DestLen); + Dest := Pointer(Result); + while Source < SourceEnd do begin + case Source^ of + #10, WideLineSeparator: + begin + if Style in [tlbsCRLF, tlbsCR] then + begin + Dest^ := #13; + Inc(Dest); + end; + if Style in [tlbsCRLF, tlbsLF] then + begin + Dest^ := #10; + Inc(Dest); + end; + Inc(Source); + end; + #13: + begin + if Style in [tlbsCRLF, tlbsCR] then + begin + Dest^ := #13; + Inc(Dest); + end; + if Style in [tlbsCRLF, tlbsLF] then + begin + Dest^ := #10; + Inc(Dest); + end; + Inc(Source); + if Source^ = #10 then Inc(Source); + end; + else + Dest^ := Source^; + Inc(Dest); + Inc(Source); + end; + end; +end; + +function WideWrapText(const Line, BreakStr: WideString; const BreakChars: TSysCharSet; + MaxCol: Integer): WideString; + + function WideCharIn(C: WideChar; SysCharSet: TSysCharSet): Boolean; + begin + Result := (C <= High(AnsiChar)) and (AnsiChar(C) in SysCharSet); + end; + +const + QuoteChars = ['''', '"']; +var + Col, Pos: Integer; + LinePos, LineLen: Integer; + BreakLen, BreakPos: Integer; + QuoteChar, CurChar: WideChar; + ExistingBreak: Boolean; +begin + Col := 1; + Pos := 1; + LinePos := 1; + BreakPos := 0; + QuoteChar := ' '; + ExistingBreak := False; + LineLen := Length(Line); + BreakLen := Length(BreakStr); + Result := ''; + while Pos <= LineLen do + begin + CurChar := Line[Pos]; + if CurChar = BreakStr[1] then + begin + if QuoteChar = ' ' then + begin + ExistingBreak := WideSameText(BreakStr, Copy(Line, Pos, BreakLen)); + if ExistingBreak then + begin + Inc(Pos, BreakLen-1); + BreakPos := Pos; + end; + end + end + else if WideCharIn(CurChar, BreakChars) then + begin + if QuoteChar = ' ' then BreakPos := Pos + end + else if WideCharIn(CurChar, QuoteChars) then + begin + if CurChar = QuoteChar then + QuoteChar := ' ' + else if QuoteChar = ' ' then + QuoteChar := CurChar; + end; + Inc(Pos); + Inc(Col); + if not (WideCharIn(QuoteChar, QuoteChars)) and (ExistingBreak or + ((Col > MaxCol) and (BreakPos > LinePos))) then + begin + Col := Pos - BreakPos; + Result := Result + Copy(Line, LinePos, BreakPos - LinePos + 1); + if not (WideCharIn(CurChar, QuoteChars)) then + while Pos <= LineLen do + begin + if WideCharIn(Line[Pos], BreakChars) then + Inc(Pos) + else if Copy(Line, Pos, Length(sLineBreak)) = sLineBreak then + Inc(Pos, Length(sLineBreak)) + else + break; + end; + if not ExistingBreak and (Pos < LineLen) then + Result := Result + BreakStr; + Inc(BreakPos); + LinePos := BreakPos; + ExistingBreak := False; + end; + end; + Result := Result + Copy(Line, LinePos, MaxInt); +end; + +function WideWrapText(const Line: WideString; MaxCol: Integer): WideString; +begin + Result := WideWrapText(Line, sLineBreak, [' ', '-', #9], MaxCol); { do not localize } +end; + +function WideIncludeTrailingBackslash(const S: WideString): WideString; +begin + Result := WideIncludeTrailingPathDelimiter(S); +end; + +function WideIncludeTrailingPathDelimiter(const S: WideString): WideString; +begin + Result := S; + if not WideIsPathDelimiter(Result, Length(Result)) then Result := Result + PathDelim; +end; + +function WideExcludeTrailingBackslash(const S: WideString): WideString; +begin + Result := WideExcludeTrailingPathDelimiter(S); +end; + +function WideExcludeTrailingPathDelimiter(const S: WideString): WideString; +begin + Result := S; + if WideIsPathDelimiter(Result, Length(Result)) then + SetLength(Result, Length(Result)-1); +end; + +function WideIsDelimiter(const Delimiters, S: WideString; Index: Integer): Boolean; +begin + Result := False; + if (Index <= 0) or (Index > Length(S)) then exit; + Result := WStrScan(PWideChar(Delimiters), S[Index]) <> nil; +end; + +function WideIsPathDelimiter(const S: WideString; Index: Integer): Boolean; +begin + Result := (Index > 0) and (Index <= Length(S)) and (S[Index] = PathDelim); +end; + +function WideLastDelimiter(const Delimiters, S: WideString): Integer; +var + P: PWideChar; +begin + Result := Length(S); + P := PWideChar(Delimiters); + while Result > 0 do + begin + if (S[Result] <> #0) and (WStrScan(P, S[Result]) <> nil) then + Exit; + Dec(Result); + end; +end; + +function WideChangeFileExt(const FileName, Extension: WideString): WideString; +var + I: Integer; +begin + I := WideLastDelimiter('.\:',Filename); + if (I = 0) or (FileName[I] <> '.') then I := MaxInt; + Result := Copy(FileName, 1, I - 1) + Extension; +end; + +function WideExtractFilePath(const FileName: WideString): WideString; +var + I: Integer; +begin + I := WideLastDelimiter('\:', FileName); + Result := Copy(FileName, 1, I); +end; + +function WideExtractFileDir(const FileName: WideString): WideString; +var + I: Integer; +begin + I := WideLastDelimiter(DriveDelim + PathDelim,Filename); + if (I > 1) and (FileName[I] = PathDelim) and + (not (FileName[I - 1] in [WideChar(PathDelim), WideChar(DriveDelim)])) then Dec(I); + Result := Copy(FileName, 1, I); +end; + +function WideExtractFileDrive(const FileName: WideString): WideString; +var + I, J: Integer; +begin + if (Length(FileName) >= 2) and (FileName[2] = DriveDelim) then + Result := Copy(FileName, 1, 2) + else if (Length(FileName) >= 2) and (FileName[1] = PathDelim) and + (FileName[2] = PathDelim) then + begin + J := 0; + I := 3; + While (I < Length(FileName)) and (J < 2) do + begin + if FileName[I] = PathDelim then Inc(J); + if J < 2 then Inc(I); + end; + if FileName[I] = PathDelim then Dec(I); + Result := Copy(FileName, 1, I); + end else Result := ''; +end; + +function WideExtractFileName(const FileName: WideString): WideString; +var + I: Integer; +begin + I := WideLastDelimiter('\:', FileName); + Result := Copy(FileName, I + 1, MaxInt); +end; + +function WideExtractFileExt(const FileName: WideString): WideString; +var + I: Integer; +begin + I := WideLastDelimiter('.\:', FileName); + if (I > 0) and (FileName[I] = '.') then + Result := Copy(FileName, I, MaxInt) else + Result := ''; +end; + +function WideExtractRelativePath(const BaseName, DestName: WideString): WideString; +var + BasePath, DestPath: WideString; + BaseLead, DestLead: PWideChar; + BasePtr, DestPtr: PWideChar; + + function WideExtractFilePathNoDrive(const FileName: WideString): WideString; + begin + Result := WideExtractFilePath(FileName); + Delete(Result, 1, Length(WideExtractFileDrive(FileName))); + end; + + function Next(var Lead: PWideChar): PWideChar; + begin + Result := Lead; + if Result = nil then Exit; + Lead := WStrScan(Lead, PathDelim); + if Lead <> nil then + begin + Lead^ := #0; + Inc(Lead); + end; + end; + +begin + if WideSameText(WideExtractFileDrive(BaseName), WideExtractFileDrive(DestName)) then + begin + BasePath := WideExtractFilePathNoDrive(BaseName); + DestPath := WideExtractFilePathNoDrive(DestName); + BaseLead := Pointer(BasePath); + BasePtr := Next(BaseLead); + DestLead := Pointer(DestPath); + DestPtr := Next(DestLead); + while (BasePtr <> nil) and (DestPtr <> nil) and WideSameText(BasePtr, DestPtr) do + begin + BasePtr := Next(BaseLead); + DestPtr := Next(DestLead); + end; + Result := ''; + while BaseLead <> nil do + begin + Result := Result + '..' + PathDelim; { Do not localize } + Next(BaseLead); + end; + if (DestPtr <> nil) and (DestPtr^ <> #0) then + Result := Result + DestPtr + PathDelim; + if DestLead <> nil then + Result := Result + DestLead; // destlead already has a trailing backslash + Result := Result + WideExtractFileName(DestName); + end + else + Result := DestName; +end; + +function WideExpandFileName(const FileName: WideString): WideString; +var + FName: PWideChar; + Buffer: array[0..MAX_PATH - 1] of WideChar; +begin + SetString(Result, Buffer, Tnt_GetFullPathNameW(PWideChar(FileName), MAX_PATH, Buffer, FName)); +end; + +function WideExtractShortPathName(const FileName: WideString): WideString; +var + Buffer: array[0..MAX_PATH - 1] of WideChar; +begin + SetString(Result, Buffer, Tnt_GetShortPathNameW(PWideChar(FileName), Buffer, MAX_PATH)); +end; + +function WideFileCreate(const FileName: WideString): Integer; +begin + Result := Integer(Tnt_CreateFileW(PWideChar(FileName), GENERIC_READ or GENERIC_WRITE, + 0, nil, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0)) +end; + +function WideFileOpen(const FileName: WideString; Mode: LongWord): Integer; +const + AccessMode: array[0..2] of LongWord = ( + GENERIC_READ, + GENERIC_WRITE, + GENERIC_READ or GENERIC_WRITE); + ShareMode: array[0..4] of LongWord = ( + 0, + 0, + FILE_SHARE_READ, + FILE_SHARE_WRITE, + FILE_SHARE_READ or FILE_SHARE_WRITE); +begin + Result := Integer(Tnt_CreateFileW(PWideChar(FileName), AccessMode[Mode and 3], + ShareMode[(Mode and $F0) shr 4], nil, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, 0)); +end; + +function WideFileAge(const FileName: WideString): Integer; +var + Handle: THandle; + FindData: TWin32FindDataW; + LocalFileTime: TFileTime; +begin + Handle := Tnt_FindFirstFileW(PWideChar(FileName), FindData); + if Handle <> INVALID_HANDLE_VALUE then + begin + Windows.FindClose(Handle); + if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then + begin + FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime); + if FileTimeToDosDateTime(LocalFileTime, LongRec(Result).Hi, LongRec(Result).Lo) then + Exit + end; + end; + Result := -1; +end; + +function WideFileAge(const FileName: WideString; out FileDateTime: TDateTime): Boolean; +var + Handle: THandle; + FindData: TWin32FindDataW; + LSystemTime: TSystemTime; + LocalFileTime: TFileTime; +begin + Result := False; + Handle := Tnt_FindFirstFileW(PWideChar(FileName), FindData); + if Handle <> INVALID_HANDLE_VALUE then + begin + Windows.FindClose(Handle); + if (FindData.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY) = 0 then + begin + Result := True; + FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime); + FileTimeToSystemTime(LocalFileTime, LSystemTime); + with LSystemTime do + FileDateTime := EncodeDate(wYear, wMonth, wDay) + + EncodeTime(wHour, wMinute, wSecond, wMilliSeconds); + end; + end; +end; + +function WideDirectoryExists(const Name: WideString): Boolean; +var + Code: Cardinal; +begin + Code := WideFileGetAttr(Name); + Result := (Code <> INVALID_FILE_ATTRIBUTES) and ((FILE_ATTRIBUTE_DIRECTORY and Code) <> 0); +end; + +function WideFileExists(const Name: WideString): Boolean; +var + Code: Cardinal; +begin + Code := WideFileGetAttr(Name); + Result := (Code <> INVALID_FILE_ATTRIBUTES) and ((FILE_ATTRIBUTE_DIRECTORY and Code) = 0); +end; + +function WideFileGetAttr(const FileName: WideString): Cardinal; +begin + Result := Tnt_GetFileAttributesW(PWideChar(FileName)); +end; + +function WideFileSetAttr(const FileName: WideString; Attr: Integer): Boolean; +begin + Result := Tnt_SetFileAttributesW(PWideChar(FileName), Attr) +end; + +function WideFileIsReadOnly(const FileName: WideString): Boolean; +begin + Result := (Tnt_GetFileAttributesW(PWideChar(FileName)) and faReadOnly) <> 0; +end; + +function WideFileSetReadOnly(const FileName: WideString; ReadOnly: Boolean): Boolean; +var + Flags: Integer; +begin + Result := False; + Flags := Tnt_GetFileAttributesW(PWideChar(FileName)); + if Flags = -1 then Exit; + if ReadOnly then + Flags := Flags or faReadOnly + else + Flags := Flags and not faReadOnly; + Result := Tnt_SetFileAttributesW(PWideChar(FileName), Flags); +end; + +function WideForceDirectories(Dir: WideString): Boolean; +begin + Result := True; + if Length(Dir) = 0 then + raise ETntGeneralError.Create( + {$IFNDEF FPC} SCannotCreateDir {$ELSE} SCannotCreateEmptyDir {$ENDIF}); + Dir := WideExcludeTrailingBackslash(Dir); + if (Length(Dir) < 3) or WideDirectoryExists(Dir) + or (WideExtractFilePath(Dir) = Dir) then Exit; // avoid 'xyz:\' problem. + Result := WideForceDirectories(WideExtractFilePath(Dir)); + if Result then + Result := Tnt_CreateDirectoryW(PWideChar(Dir), nil) +end; + +function WideFileSearch(const Name, DirList: WideString): WideString; +var + I, P, L: Integer; + C: WideChar; +begin + Result := Name; + P := 1; + L := Length(DirList); + while True do + begin + if WideFileExists(Result) then Exit; + while (P <= L) and (DirList[P] = PathSep) do Inc(P); + if P > L then Break; + I := P; + while (P <= L) and (DirList[P] <> PathSep) do + Inc(P); + Result := Copy(DirList, I, P - I); + C := TntWideLastChar(Result); + if (C <> DriveDelim) and (C <> PathDelim) then + Result := Result + PathDelim; + Result := Result + Name; + end; + Result := ''; +end; + +function WideRenameFile(const OldName, NewName: WideString): Boolean; +begin + Result := Tnt_MoveFileW(PWideChar(OldName), PWideChar(NewName)) +end; + +function WideDeleteFile(const FileName: WideString): Boolean; +begin + Result := Tnt_DeleteFileW(PWideChar(FileName)) +end; + +function WideCopyFile(const FromFile, ToFile: WideString; FailIfExists: Boolean): Boolean; +begin + Result := Tnt_CopyFileW(PWideChar(FromFile), PWideChar(ToFile), FailIfExists) +end; + +function _WideFindMatchingFile(var F: TSearchRecW): Integer; +var + LocalFileTime: TFileTime; +begin + with F do + begin + while FindData.dwFileAttributes and ExcludeAttr <> 0 do + if not Tnt_FindNextFileW(FindHandle, FindData) then + begin + Result := GetLastError; + Exit; + end; + FileTimeToLocalFileTime(FindData.ftLastWriteTime, LocalFileTime); + FileTimeToDosDateTime(LocalFileTime, LongRec(Time).Hi, LongRec(Time).Lo); + Size := (Int64(FindData.nFileSizeHigh) shl 32) + FindData.nFileSizeLow; + Attr := FindData.dwFileAttributes; + Name := FindData.cFileName; + end; + Result := 0; +end; + +function WideFindFirst(const Path: WideString; Attr: Integer; var F: TSearchRecW): Integer; +const + faSpecial = faHidden or faSysFile {$IFNDEF COMPILER_9_UP} or faVolumeID {$ENDIF} or faDirectory; +begin + F.ExcludeAttr := not Attr and faSpecial; + F.FindHandle := Tnt_FindFirstFileW(PWideChar(Path), F.FindData); + if F.FindHandle <> INVALID_HANDLE_VALUE then + begin + Result := _WideFindMatchingFile(F); + if Result <> 0 then WideFindClose(F); + end else + Result := GetLastError; +end; + +function WideFindNext(var F: TSearchRecW): Integer; +begin + if Tnt_FindNextFileW(F.FindHandle, F.FindData) then + Result := _WideFindMatchingFile(F) else + Result := GetLastError; +end; + +procedure WideFindClose(var F: TSearchRecW); +begin + if F.FindHandle <> INVALID_HANDLE_VALUE then + begin + Windows.FindClose(F.FindHandle); + F.FindHandle := INVALID_HANDLE_VALUE; + end; +end; + +function WideCreateDir(const Dir: WideString): Boolean; +begin + Result := Tnt_CreateDirectoryW(PWideChar(Dir), nil); +end; + +function WideRemoveDir(const Dir: WideString): Boolean; +begin + Result := Tnt_RemoveDirectoryW(PWideChar(Dir)); +end; + +function WideGetCurrentDir: WideString; +begin + SetLength(Result, MAX_PATH); + Tnt_GetCurrentDirectoryW(MAX_PATH, PWideChar(Result)); + Result := PWideChar(Result); +end; + +function WideSetCurrentDir(const Dir: WideString): Boolean; +begin + Result := Tnt_SetCurrentDirectoryW(PWideChar(Dir)); +end; + +//============================================================================================= +//== DATE/TIME STRING PARSING ================================================================ +//============================================================================================= + +{$IFDEF FPC} +const + VAR_TIMEVALUEONLY = 1; + VAR_DATEVALUEONLY = 2; +{$ENDIF} + +function _IntTryStrToDateTime(Str: WideString; Flags: Integer; out DateTime: TDateTime): HResult; +begin + Result := VarDateFromStr( + {$IFDEF FPC} POLECHAR(Str) {$ELSE} Str {$ENDIF}, + GetThreadLocale, Flags, Double(DateTime)); + if (not Succeeded(Result)) then begin + if (Flags = VAR_TIMEVALUEONLY) + and SysUtils.TryStrToTime{TNT-ALLOW TryStrToTime}(Str, DateTime) then + Result := S_OK // SysUtils seems confident (works for date = "dd.MM.yy" and time = "H.mm.ss") + else if (Flags = VAR_DATEVALUEONLY) + and SysUtils.TryStrToDate{TNT-ALLOW TryStrToDate}(Str, DateTime) then + Result := S_OK // SysUtils seems confident + else if (Flags = 0) + and SysUtils.TryStrToDateTime{TNT-ALLOW TryStrToDateTime}(Str, DateTime) then + Result := S_OK // SysUtils seems confident + end; +end; + +function TntTryStrToDateTime(Str: WideString; out DateTime: TDateTime): Boolean; +begin + Result := Succeeded(_IntTryStrToDateTime(Str, 0, DateTime)); +end; + +function TntTryStrToDate(Str: WideString; out DateTime: TDateTime): Boolean; +begin + Result := Succeeded(_IntTryStrToDateTime(Str, VAR_DATEVALUEONLY, DateTime)); +end; + +function TntTryStrToTime(Str: WideString; out DateTime: TDateTime): Boolean; +begin + Result := Succeeded(_IntTryStrToDateTime(Str, VAR_TIMEVALUEONLY, DateTime)); +end; + +function ValidDateTimeStr(Str: WideString): Boolean; +var + Temp: TDateTime; +begin + Result := Succeeded(_IntTryStrToDateTime(Str, 0, Temp)); +end; + +function ValidDateStr(Str: WideString): Boolean; +var + Temp: TDateTime; +begin + Result := Succeeded(_IntTryStrToDateTime(Str, VAR_DATEVALUEONLY, Temp)); +end; + +function ValidTimeStr(Str: WideString): Boolean; +var + Temp: TDateTime; +begin + Result := Succeeded(_IntTryStrToDateTime(Str, VAR_TIMEVALUEONLY, Temp)); +end; + +function TntStrToDateTimeDef(Str: WideString; Default: TDateTime): TDateTime; +begin + if not TntTryStrToDateTime(Str, Result) then + Result := Default; +end; + +function TntStrToDateDef(Str: WideString; Default: TDateTime): TDateTime; +begin + if not TntTryStrToDate(Str, Result) then + Result := Default; +end; + +function TntStrToTimeDef(Str: WideString; Default: TDateTime): TDateTime; +begin + if not TntTryStrToTime(Str, Result) then + Result := Default; +end; + +function _IntStrToDateTime(Str: WideString; Flags: Integer; ErrorFormatStr: WideString): TDateTime; +begin + try + OleCheck(_IntTryStrToDateTime(Str, Flags, Result)); + except + on E: Exception do begin + E.Message := E.Message + CRLF + WideFormat(ErrorFormatStr, [Str]); + raise EConvertError.Create(E.Message); + end; + end; +end; + +function TntStrToDateTime(Str: WideString): TDateTime; +begin + Result := _IntStrToDateTime(Str, 0, SInvalidDateTime); +end; + +function TntStrToDate(Str: WideString): TDateTime; +begin + Result := _IntStrToDateTime(Str, VAR_DATEVALUEONLY, + {$IFNDEF FPC} SInvalidDate {$ELSE} SInvalidDateTime {$ENDIF}); +end; + +function TntStrToTime(Str: WideString): TDateTime; +begin + Result := _IntStrToDateTime(Str, VAR_TIMEVALUEONLY, + {$IFNDEF FPC} SInvalidTime {$ELSE} SInvalidDateTime {$ENDIF}); +end; + +//============================================================================================= +//== CURRENCY STRING PARSING ================================================================= +//============================================================================================= + +function TntCurrToStr(Value: Currency; lpFormat: PCurrencyFmtW = nil): WideString; +const + MAX_BUFF_SIZE = 64; // can a currency string actually be larger? +var + ValueStr: WideString; +begin + // format lpValue using ENG-US settings + ValueStr := ENG_US_FloatToStr(Value); + // get currency format + SetLength(Result, MAX_BUFF_SIZE); + if 0 = Tnt_GetCurrencyFormatW(GetThreadLocale, 0, PWideChar(ValueStr), + lpFormat, PWideChar(Result), Length(Result)) + then begin + RaiseLastOSError; + end; + Result := PWideChar(Result); +end; + +function TntStrToCurr(const S: WideString): Currency; +begin + try + OleCheck(VarCyFromStr( + {$IFDEF FPC} POLECHAR(S) {$ELSE} S {$ENDIF}, + GetThreadLocale, 0, Result)); + except + on E: Exception do begin + E.Message := E.Message + CRLF + WideFormat(SInvalidCurrency, [S]); + raise EConvertError.Create(E.Message); + end; + end; +end; + +function ValidCurrencyStr(const S: WideString): Boolean; +var + Dummy: Currency; +begin + Result := Succeeded(VarCyFromStr( + {$IFDEF FPC} POLECHAR(S) {$ELSE} S {$ENDIF}, + GetThreadLocale, 0, Dummy)); +end; + +function TntStrToCurrDef(const S: WideString; const Default: Currency): Currency; +begin + if not Succeeded(VarCyFromStr( + {$IFDEF FPC} POLECHAR(S) {$ELSE} S {$ENDIF}, + GetThreadLocale, 0, Result)) then + Result := Default; +end; + +threadvar + Currency_DecimalSep: WideString; + Currency_ThousandSep: WideString; + Currency_CurrencySymbol: WideString; + +function GetDefaultCurrencyFmt: TCurrencyFmtW; +begin + ZeroMemory(@Result, SizeOf(Result)); + Result.NumDigits := StrToIntDef(WideGetLocaleStr(GetThreadLocale, LOCALE_ICURRDIGITS, '2'), 2); + Result.LeadingZero := StrToIntDef(WideGetLocaleStr(GetThreadLocale, LOCALE_ILZERO, '1'), 1); + Result.Grouping := StrToIntDef(Copy(WideGetLocaleStr(GetThreadLocale, LOCALE_SMONGROUPING, '3;0'), 1, 1), 3); + Currency_DecimalSep := WideGetLocaleStr(GetThreadLocale, LOCALE_SMONDECIMALSEP, '.'); + Result.lpDecimalSep := {$IFNDEF FPC} PWideChar(Currency_DecimalSep) + {$ELSE} LPTSTR(PWideChar(Currency_DecimalSep)) {$ENDIF}; + Currency_ThousandSep := WideGetLocaleStr(GetThreadLocale, LOCALE_SMONTHOUSANDSEP, ','); + Result.lpThousandSep := {$IFNDEF FPC} PWideChar(Currency_ThousandSep) + {$ELSE} LPTSTR(PWideChar(Currency_ThousandSep)) {$ENDIF}; + Result.NegativeOrder := StrToIntDef(WideGetLocaleStr(GetThreadLocale, LOCALE_INEGCURR, '0'), 0); + Result.PositiveOrder := StrToIntDef(WideGetLocaleStr(GetThreadLocale, LOCALE_ICURRENCY, '0'), 0); + Currency_CurrencySymbol := WideGetLocaleStr(GetThreadLocale, LOCALE_SCURRENCY, ''); + Result.lpCurrencySymbol := {$IFNDEF FPC} PWideChar(Currency_CurrencySymbol) + {$ELSE} LPTSTR(PWideChar(Currency_CurrencySymbol)) {$ENDIF}; +end; + +//============================================================================================= + +{$IFDEF FPC} +function GetLocaleStr(Locale, LocaleType: Integer; const Default: string): string; +var + L: Integer; + Buffer: array[0..255] of Char; +begin + L := GetLocaleInfo(Locale, LocaleType, Buffer, SizeOf(Buffer)); + if L > 0 then SetString(Result, Buffer, L - 1) else Result := Default; +end; +{$ENDIF} + +function WideGetLocaleStr(LocaleID: LCID; LocaleType: Integer; const Default: WideString): WideString; +var + L: Integer; +begin + if (not Win32PlatformIsUnicode) then + Result := GetLocaleStr{TNT-ALLOW GetLocaleStr}(LocaleID, LocaleType, Default) + else begin + SetLength(Result, 255); + L := GetLocaleInfoW(LocaleID, LocaleType, PWideChar(Result), Length(Result)); + if L > 0 then + SetLength(Result, L - 1) + else + Result := Default; + end; +end; + +function WideSysErrorMessage(ErrorCode: Integer): WideString; +begin + Result := WideLibraryErrorMessage('system', 0, ErrorCode); +end; + +function WideLibraryErrorMessage(const LibName: WideString; Dll: THandle; ErrorCode: Integer): WideString; +var + Len: Integer; + AnsiResult: AnsiString; + Flags: Cardinal; +begin + Flags := FORMAT_MESSAGE_FROM_SYSTEM or FORMAT_MESSAGE_IGNORE_INSERTS or FORMAT_MESSAGE_ARGUMENT_ARRAY; + if Dll <> 0 then + Flags := Flags or FORMAT_MESSAGE_FROM_HMODULE; + if Win32PlatformIsUnicode then begin + SetLength(Result, 256); + Len := FormatMessageW(Flags, Pointer(Dll), ErrorCode, 0, PWideChar(Result), Length(Result), nil); + SetLength(Result, Len); + end else begin + SetLength(AnsiResult, 256); + Len := FormatMessageA(Flags, Pointer(Dll), ErrorCode, 0, PAnsiChar(AnsiResult), Length(AnsiResult), nil); + SetLength(AnsiResult, Len); + Result := AnsiResult; + end; + if Trim(Result) = '' then + Result := WideFormat('Unspecified error (%d) from %s.', [ErrorCode, LibName]); +end; + +{$IFNDEF COMPILER_7_UP} +function CheckWin32Version(AMajor: Integer; AMinor: Integer = 0): Boolean; +begin + Result := (Win32MajorVersion > AMajor) or + ((Win32MajorVersion = AMajor) and + (Win32MinorVersion >= AMinor)); +end; +{$ENDIF} + +function WinCheckH(RetVal: Cardinal): Cardinal; +begin + if RetVal = 0 then RaiseLastOSError; + Result := RetVal; +end; + +function WinCheckFileH(RetVal: Cardinal): Cardinal; +begin + if RetVal = INVALID_HANDLE_VALUE then RaiseLastOSError; + Result := RetVal; +end; + +function WinCheckP(RetVal: Pointer): Pointer; +begin + if RetVal = nil then RaiseLastOSError; + Result := RetVal; +end; + +function WideGetModuleFileName(Instance: HModule): WideString; +begin + SetLength(Result, MAX_PATH); + WinCheckH(Tnt_GetModuleFileNameW(Instance, PWideChar(Result), Length(Result))); + Result := PWideChar(Result) +end; + +function WideSafeLoadLibrary(const Filename: Widestring; ErrorMode: UINT): HMODULE; +var + OldMode: UINT; + FPUControlWord: Word; +begin + OldMode := SetErrorMode(ErrorMode); + try + asm + FNSTCW FPUControlWord + end; + try + Result := Tnt_LoadLibraryW(PWideChar(Filename)); + finally + asm + FNCLEX + FLDCW FPUControlWord + end; + end; + finally + SetErrorMode(OldMode); + end; +end; + +{$IFNDEF FPC} +function WideLoadPackage(const Name: Widestring): HMODULE; +begin + Result := WideSafeLoadLibrary(Name); + if Result = 0 then + begin + raise EPackageError.CreateFmt(sErrorLoadingPackage, [Name, WideSysErrorMessage(GetLastError)]); + end; + try + InitializePackage(Result); + except + FreeLibrary(Result); + raise; + end; +end; +{$ENDIF} + +function _WideCharType(WC: WideChar; dwInfoType: Cardinal): Word; +begin + Win32Check(Tnt_GetStringTypeExW(GetThreadLocale, dwInfoType, PWideChar(@WC), 1, Result)) +end; + +function IsWideCharUpper(WC: WideChar): Boolean; +begin + Result := (_WideCharType(WC, CT_CTYPE1) and C1_UPPER) <> 0; +end; + +function IsWideCharLower(WC: WideChar): Boolean; +begin + Result := (_WideCharType(WC, CT_CTYPE1) and C1_LOWER) <> 0; +end; + +function IsWideCharDigit(WC: WideChar): Boolean; +begin + Result := (_WideCharType(WC, CT_CTYPE1) and C1_DIGIT) <> 0; +end; + +function IsWideCharSpace(WC: WideChar): Boolean; +begin + Result := (_WideCharType(WC, CT_CTYPE1) and C1_SPACE) <> 0; +end; + +function IsWideCharPunct(WC: WideChar): Boolean; +begin + Result := (_WideCharType(WC, CT_CTYPE1) and C1_PUNCT) <> 0; +end; + +function IsWideCharCntrl(WC: WideChar): Boolean; +begin + Result := (_WideCharType(WC, CT_CTYPE1) and C1_CNTRL) <> 0; +end; + +function IsWideCharBlank(WC: WideChar): Boolean; +begin + Result := (_WideCharType(WC, CT_CTYPE1) and C1_BLANK) <> 0; +end; + +function IsWideCharXDigit(WC: WideChar): Boolean; +begin + Result := (_WideCharType(WC, CT_CTYPE1) and C1_XDIGIT) <> 0; +end; + +function IsWideCharAlpha(WC: WideChar): Boolean; +begin + Result := (_WideCharType(WC, CT_CTYPE1) and C1_ALPHA) <> 0; +end; + +function IsWideCharAlphaNumeric(WC: WideChar): Boolean; +begin + Result := (_WideCharType(WC, CT_CTYPE1) and (C1_ALPHA + C1_DIGIT)) <> 0; +end; + +function WideTextPos(const SubStr, S: WideString): Integer; +begin + Result := Pos(Tnt_WideUpperCase(SubStr), Tnt_WideUpperCase(S)); +end; + +function FindDoubleTerminator(P: PWideChar): PWideChar; +begin + Result := P; + while True do begin + Result := WStrScan(Result, #0); + Inc(Result); + if Result^ = #0 then begin + Dec(Result); + break; + end; + end; +end; + +function ExtractStringArrayStr(P: PWideChar): WideString; +var + PEnd: PWideChar; +begin + PEnd := FindDoubleTerminator(P); + Inc(PEnd, 2); // move past #0#0 + SetString(Result, P, PEnd - P); +end; + +function ExtractStringFromStringArray(var P: PWideChar; Separator: WideChar = #0): WideString; +var + Start: PWideChar; +begin + Start := P; + P := WStrScan(Start, Separator); + if P = nil then begin + Result := Start; + P := WStrEnd(Start); + end else begin + SetString(Result, Start, P - Start); + Inc(P); + end; +end; + +function ExtractStringsFromStringArray(P: PWideChar; Separator: WideChar = #0): TWideStringDynArray; +const + GROW_COUNT = 256; +var + Count: Integer; + Item: WideString; +begin + Count := 0; + SetLength(Result, GROW_COUNT); + Item := ExtractStringFromStringArray(P, Separator); + While Item <> '' do begin + if Count > High(Result) then + SetLength(Result, Length(Result) + GROW_COUNT); + Result[Count] := Item; + Inc(Count); + Item := ExtractStringFromStringArray(P, Separator); + end; + SetLength(Result, Count); +end; + +function IsWideCharMappableToAnsi(const WC: WideChar): Boolean; +var + UsedDefaultChar: BOOL; +begin + WideCharToMultiByte(DefaultSystemCodePage, 0, PWideChar(@WC), 1, nil, 0, nil, @UsedDefaultChar); + Result := not UsedDefaultChar; +end; + +function IsWideStringMappableToAnsi(const WS: WideString): Boolean; +var + UsedDefaultChar: BOOL; +begin + WideCharToMultiByte(DefaultSystemCodePage, 0, PWideChar(WS), Length(WS), nil, 0, nil, @UsedDefaultChar); + Result := not UsedDefaultChar; +end; + +function IsRTF(const Value: WideString): Boolean; +const + RTF_BEGIN_1 = WideString('{\RTF'); + RTF_BEGIN_2 = WideString('{URTF'); +begin + Result := (WideTextPos(RTF_BEGIN_1, Value) = 1) + or (WideTextPos(RTF_BEGIN_2, Value) = 1); +end; + +{$IFDEF COMPILER_7_UP} +var + Cached_ENG_US_FormatSettings: TFormatSettings; + Cached_ENG_US_FormatSettings_Time: Cardinal; + +function ENG_US_FormatSettings: TFormatSettings; +begin + if Cached_ENG_US_FormatSettings_Time = _SettingChangeTime then + Result := Cached_ENG_US_FormatSettings + else begin + GetLocaleFormatSettings(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US)), Result); + Result.DecimalSeparator := '.'; // ignore overrides + Cached_ENG_US_FormatSettings := Result; + Cached_ENG_US_FormatSettings_Time := _SettingChangeTime; + end; + end; + +function ENG_US_FloatToStr(Value: Extended): WideString; +begin + Result := FloatToStr(Value, ENG_US_FormatSettings); +end; + +function ENG_US_StrToFloat(const S: WideString): Extended; +begin + if not TextToFloat(PAnsiChar(AnsiString(S)), Result, fvExtended, ENG_US_FormatSettings) then + Result := StrToFloat(S); // try using native format +end; + +{$ELSE} + +function ENG_US_FloatToStr(Value: Extended): WideString; +var + SaveDecimalSep: AnsiChar; +begin + SaveDecimalSep := SysUtils.DecimalSeparator; + try + SysUtils.DecimalSeparator := '.'; + Result := FloatToStr(Value); + finally + SysUtils.DecimalSeparator := SaveDecimalSep; + end; +end; + +function ENG_US_StrToFloat(const S: WideString): Extended; +var + SaveDecimalSep: AnsiChar; +begin + try + SaveDecimalSep := SysUtils.DecimalSeparator; + try + SysUtils.DecimalSeparator := '.'; + Result := StrToFloat(S); + finally + SysUtils.DecimalSeparator := SaveDecimalSep; + end; + except + if SysUtils.DecimalSeparator <> '.' then + Result := StrToFloat(S) // try using native format + else + raise; + end; +end; +{$ENDIF} + +//--------------------------------------------------------------------------------------------- +// Tnt - Variants +//--------------------------------------------------------------------------------------------- + +initialization + Win32PlatformIsUnicode := (Win32Platform = VER_PLATFORM_WIN32_NT); + Win32PlatformIsXP := ((Win32MajorVersion = 5) and (Win32MinorVersion >= 1)) + or (Win32MajorVersion > 5); + Win32PlatformIs2003 := ((Win32MajorVersion = 5) and (Win32MinorVersion >= 2)) + or (Win32MajorVersion > 5); + Win32PlatformIsVista := (Win32MajorVersion >= 6); + +finalization + Currency_DecimalSep := ''; {make memory sleuth happy} + Currency_ThousandSep := ''; {make memory sleuth happy} + Currency_CurrencySymbol := ''; {make memory sleuth happy} + +end. diff --git a/cmake/src/lib/TntUnicodeControls/TntSystem.pas b/cmake/src/lib/TntUnicodeControls/TntSystem.pas new file mode 100644 index 00000000..e613ce0c --- /dev/null +++ b/cmake/src/lib/TntUnicodeControls/TntSystem.pas @@ -0,0 +1,1427 @@ + +{*****************************************************************************} +{ } +{ Tnt Delphi Unicode Controls } +{ http://www.tntware.com/delphicontrols/unicode/ } +{ Version: 2.3.0 } +{ } +{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } +{ } +{*****************************************************************************} + +unit TntSystem; + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +{$INCLUDE TntCompilers.inc} + +{*****************************************************************************} +{ Special thanks go to Francisco Leong for originating the design for } +{ WideString-enabled resourcestrings. } +{*****************************************************************************} + +interface + +uses + Windows; + +// These functions should not be used by Delphi code since conversions are implicit. +{TNT-WARN WideCharToString} +{TNT-WARN WideCharLenToString} +{TNT-WARN WideCharToStrVar} +{TNT-WARN WideCharLenToStrVar} +{TNT-WARN StringToWideChar} + +// ................ ANSI TYPES ................ +{TNT-WARN Char} +{TNT-WARN PChar} +{TNT-WARN String} + +{TNT-WARN CP_ACP} // <-- use DefaultSystemCodePage +function DefaultSystemCodePage: Cardinal; // implicitly used when converting AnsiString <--> WideString. + +{$IFNDEF FPC} +var + WideCustomLoadResString: function(ResStringRec: PResStringRec; var Value: WideString): Boolean; +{$ENDIF} + +{TNT-WARN LoadResString} +function WideLoadResString(ResStringRec: PResStringRec): WideString; +{TNT-WARN ParamCount} +function WideParamCount: Integer; +{TNT-WARN ParamStr} +function WideParamStr(Index: Integer): WideString; + +// ......... introduced ......... + +const + { Each Unicode stream should begin with the code U+FEFF, } + { which the standard defines as the *byte order mark*. } + UNICODE_BOM = WideChar($FEFF); + UNICODE_BOM_SWAPPED = WideChar($FFFE); + UTF8_BOM = AnsiString(#$EF#$BB#$BF); + +function WideStringToUTF8(const S: WideString): AnsiString; +function UTF8ToWideString(const S: AnsiString): WideString; + +function WideStringToUTF7(const W: WideString): AnsiString; +function UTF7ToWideString(const S: AnsiString): WideString; + +function StringToWideStringEx(const S: AnsiString; CodePage: Cardinal): WideString; +function WideStringToStringEx(const WS: WideString; CodePage: Cardinal): AnsiString; + +function UCS2ToWideString(const Value: AnsiString): WideString; +function WideStringToUCS2(const Value: WideString): AnsiString; + +function CharSetToCodePage(ciCharset: UINT): Cardinal; +function LCIDToCodePage(ALcid: LCID): Cardinal; +function KeyboardCodePage: Cardinal; +function KeyUnicode(CharCode: Word): WideChar; + +procedure StrSwapByteOrder(Str: PWideChar); + +{$IFDEF USE_SYSTEM_OVERRIDES} + +type + TTntSystemUpdate = + (tsWideResourceStrings + {$IFNDEF COMPILER_9_UP}, tsFixImplicitCodePage, tsFixWideStrConcat, tsFixWideFormat {$ENDIF} + ); + TTntSystemUpdateSet = set of TTntSystemUpdate; + +const + AllTntSystemUpdates = [Low(TTntSystemUpdate)..High(TTntSystemUpdate)]; + +procedure InstallTntSystemUpdates(Updates: TTntSystemUpdateSet = AllTntSystemUpdates); + +{$ENDIF USE_SYSTEM_OVERRIDES} + +implementation + +uses + SysUtils, Variants, TntWindows, TntSysUtils; + +var + GDefaultSystemCodePage: Cardinal; + +function DefaultSystemCodePage: Cardinal; +begin + Result := GDefaultSystemCodePage; +end; + +{$IFDEF USE_SYSTEM_OVERRIDES} +var + IsDebugging: Boolean; +{$ENDIF USE_SYSTEM_OVERRIDES} + +function WideLoadResStringDetect(ResStringRec: PResStringRec): WideString; +var + PCustom: PAnsiChar; +begin + // custom string pointer + PCustom := PAnsiChar(ResStringRec); { I would like to use PWideChar, but this would break legacy code. } + if (StrLen{TNT-ALLOW StrLen}(PCustom) > Cardinal(Length(UTF8_BOM))) + and CompareMem(PCustom, PAnsiChar(UTF8_BOM), Length(UTF8_BOM)) then + // detected UTF8 + Result := UTF8ToWideString(PAnsiChar(PCustom + Length(UTF8_BOM))) + else + // normal + Result := PCustom; +end; + +{$IFNDEF FPC} + +function WideLoadResString(ResStringRec: PResStringRec): WideString; +const + MAX_RES_STRING_SIZE = 4097; { MSDN documents this as the maximum size of a string in table. } +var + Buffer: array [0..MAX_RES_STRING_SIZE] of WideChar; { Buffer leaves room for null terminator. } +begin + if Assigned(WideCustomLoadResString) and WideCustomLoadResString(ResStringRec, Result) then + exit; { a custom resourcestring has been loaded. } + + if ResStringRec = nil then + Result := '' + else if ResStringRec.Identifier < 64*1024 then + SetString(Result, Buffer, + Tnt_LoadStringW(FindResourceHInstance(ResStringRec.Module^), + ResStringRec.Identifier, Buffer, MAX_RES_STRING_SIZE)) + else begin + Result := WideLoadResStringDetect(ResStringRec); + end; +end; + +{$ELSE} + +function WideLoadResString(ResStringRec: PResStringRec): WideString; +begin + Result := WideLoadResStringDetect(ResStringRec); +end; + +{$ENDIF} + +function WideGetParamStr(P: PWideChar; var Param: WideString): PWideChar; +var + i, Len: Integer; + Start, S, Q: PWideChar; +begin + while True do + begin + while (P[0] <> #0) and (P[0] <= ' ') do + Inc(P); + if (P[0] = '"') and (P[1] = '"') then Inc(P, 2) else Break; + end; + Len := 0; + Start := P; + while P[0] > ' ' do + begin + if P[0] = '"' then + begin + Inc(P); + while (P[0] <> #0) and (P[0] <> '"') do + begin + Q := P + 1; + Inc(Len, Q - P); + P := Q; + end; + if P[0] <> #0 then + Inc(P); + end + else + begin + Q := P + 1; + Inc(Len, Q - P); + P := Q; + end; + end; + + SetLength(Param, Len); + + P := Start; + S := PWideChar(Param); + i := 0; + while P[0] > ' ' do + begin + if P[0] = '"' then + begin + Inc(P); + while (P[0] <> #0) and (P[0] <> '"') do + begin + Q := P + 1; + while P < Q do + begin + S[i] := P^; + Inc(P); + Inc(i); + end; + end; + if P[0] <> #0 then Inc(P); + end + else + begin + Q := P + 1; + while P < Q do + begin + S[i] := P^; + Inc(P); + Inc(i); + end; + end; + end; + + Result := P; +end; + +function WideParamCount: Integer; +var + P: PWideChar; + S: WideString; +begin + P := WideGetParamStr(GetCommandLineW, S); + Result := 0; + while True do + begin + P := WideGetParamStr(P, S); + if S = '' then Break; + Inc(Result); + end; +end; + +function WideParamStr(Index: Integer): WideString; +var + P: PWideChar; +begin + if Index = 0 then + Result := WideGetModuleFileName(0) + else + begin + P := GetCommandLineW; + while True do + begin + P := WideGetParamStr(P, Result); + if (Index = 0) or (Result = '') then Break; + Dec(Index); + end; + end; +end; + +function WideStringToUTF8(const S: WideString): AnsiString; +begin + Result := UTF8Encode(S); +end; + +function UTF8ToWideString(const S: AnsiString): WideString; +begin + Result := UTF8Decode(S); +end; + + { ======================================================================= } + { Original File: ConvertUTF7.c } + { Author: David B. Goldsmith } + { Copyright (C) 1994, 1996 Taligent, Inc. All rights reserved. } + { } + { This code is copyrighted. Under the copyright laws, this code may not } + { be copied, in whole or part, without prior written consent of Taligent. } + { } + { Taligent grants the right to use this code as long as this ENTIRE } + { copyright notice is reproduced in the code. The code is provided } + { AS-IS, AND TALIGENT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR } + { IMPLIED, INCLUDING, BUT NOT LIMITED TO IMPLIED WARRANTIES OF } + { MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT } + { WILL TALIGENT BE LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING, } + { WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS } + { INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY } + { LOSS) ARISING OUT OF THE USE OR INABILITY TO USE THIS CODE, EVEN } + { IF TALIGENT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. } + { BECAUSE SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF } + { LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE } + { LIMITATION MAY NOT APPLY TO YOU. } + { } + { RESTRICTED RIGHTS LEGEND: Use, duplication, or disclosure by the } + { government is subject to restrictions as set forth in subparagraph } + { (c)(l)(ii) of the Rights in Technical Data and Computer Software } + { clause at DFARS 252.227-7013 and FAR 52.227-19. } + { } + { This code may be protected by one or more U.S. and International } + { Patents. } + { } + { TRADEMARKS: Taligent and the Taligent Design Mark are registered } + { trademarks of Taligent, Inc. } + { ======================================================================= } + +type UCS2 = Word; + +const + _base64: AnsiString = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + _direct: AnsiString = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789''(),-./:?'; + _optional: AnsiString = '!"#$%&*;<=>@[]^_`{|}'; + _spaces: AnsiString = #9#13#10#32; + +var + base64: PAnsiChar; + invbase64: array[0..127] of SmallInt; + direct: PAnsiChar; + optional: PAnsiChar; + spaces: PAnsiChar; + mustshiftsafe: array[0..127] of AnsiChar; + mustshiftopt: array[0..127] of AnsiChar; + +var + needtables: Boolean = True; + +procedure Initialize_UTF7_Data; +begin + base64 := PAnsiChar(_base64); + direct := PAnsiChar(_direct); + optional := PAnsiChar(_optional); + spaces := PAnsiChar(_spaces); +end; + +procedure tabinit; +var + i: Integer; + limit: Integer; +begin + i := 0; + while (i < 128) do + begin + mustshiftopt[i] := #1; + mustshiftsafe[i] := #1; + invbase64[i] := -1; + Inc(i); + end { For }; + limit := Length(_Direct); + i := 0; + while (i < limit) do + begin + mustshiftopt[Integer(direct[i])] := #0; + mustshiftsafe[Integer(direct[i])] := #0; + Inc(i); + end { For }; + limit := Length(_Spaces); + i := 0; + while (i < limit) do + begin + mustshiftopt[Integer(spaces[i])] := #0; + mustshiftsafe[Integer(spaces[i])] := #0; + Inc(i); + end { For }; + limit := Length(_Optional); + i := 0; + while (i < limit) do + begin + mustshiftopt[Integer(optional[i])] := #0; + Inc(i); + end { For }; + limit := Length(_Base64); + i := 0; + while (i < limit) do + begin + invbase64[Integer(base64[i])] := i; + Inc(i); + end { For }; + needtables := False; +end; { tabinit } + +function WRITE_N_BITS(x: UCS2; n: Integer; var BITbuffer: Cardinal; var bufferbits: Integer): Integer; +begin + BITbuffer := BITbuffer or (x and (not (-1 shl n))) shl (32 - n - bufferbits); + bufferbits := bufferbits + n; + Result := bufferbits; +end; { WRITE_N_BITS } + +function READ_N_BITS(n: Integer; var BITbuffer: Cardinal; var bufferbits: Integer): UCS2; +var + buffertemp: Cardinal; +begin + buffertemp := BITbuffer shr (32 - n); + BITbuffer := BITbuffer shl n; + bufferbits := bufferbits - n; + Result := UCS2(buffertemp); +end; { READ_N_BITS } + +function ConvertUCS2toUTF7(var sourceStart: PWideChar; sourceEnd: PWideChar; + var targetStart: PAnsiChar; targetEnd: PAnsiChar; optional: Boolean; + verbose: Boolean): Integer; +var + r: UCS2; + target: PAnsiChar; + source: PWideChar; + BITbuffer: Cardinal; + bufferbits: Integer; + shifted: Boolean; + needshift: Boolean; + done: Boolean; + mustshift: PAnsiChar; +begin + Initialize_UTF7_Data; + Result := 0; + BITbuffer := 0; + bufferbits := 0; + shifted := False; + source := sourceStart; + target := targetStart; + r := 0; + if needtables then + tabinit; + if optional then + mustshift := @mustshiftopt[0] + else + mustshift := @mustshiftsafe[0]; + repeat + done := source >= sourceEnd; + if not Done then + begin + r := Word(source^); + Inc(Source); + end { If }; + needshift := (not done) and ((r > $7F) or (mustshift[r] <> #0)); + if needshift and (not shifted) then + begin + if (Target >= TargetEnd) then + begin + Result := 2; + break; + end { If }; + target^ := '+'; + Inc(target); + { Special case handling of the SHIFT_IN character } + if (r = UCS2('+')) then + begin + if (target >= targetEnd) then + begin + Result := 2; + break; + end; + target^ := '-'; + Inc(target); + end + else + shifted := True; + end { If }; + if shifted then + begin + { Either write the character to the bit buffer, or pad } + { the bit buffer out to a full base64 character. } + { } + if needshift then + WRITE_N_BITS(r, 16, BITbuffer, bufferbits) + else + WRITE_N_BITS(0, (6 - (bufferbits mod 6)) mod 6, BITbuffer, + bufferbits); + { Flush out as many full base64 characters as possible } + { from the bit buffer. } + { } + while (target < targetEnd) and (bufferbits >= 6) do + begin + Target^ := base64[READ_N_BITS(6, BITbuffer, bufferbits)]; + Inc(Target); + end { While }; + if (bufferbits >= 6) then + begin + if (target >= targetEnd) then + begin + Result := 2; + break; + end { If }; + end { If }; + if (not needshift) then + begin + { Write the explicit shift out character if } + { 1) The caller has requested we always do it, or } + { 2) The directly encoded character is in the } + { base64 set, or } + { 3) The directly encoded character is SHIFT_OUT. } + { } + if verbose or ((not done) and ((invbase64[r] >= 0) or (r = + Integer('-')))) then + begin + if (target >= targetEnd) then + begin + Result := 2; + Break; + end { If }; + Target^ := '-'; + Inc(Target); + end { If }; + shifted := False; + end { If }; + { The character can be directly encoded as ASCII. } + end { If }; + if (not needshift) and (not done) then + begin + if (target >= targetEnd) then + begin + Result := 2; + break; + end { If }; + Target^ := AnsiChar(r); + Inc(Target); + end { If }; + until (done); + sourceStart := source; + targetStart := target; +end; { ConvertUCS2toUTF7 } + +function ConvertUTF7toUCS2(var sourceStart: PAnsiChar; sourceEnd: PAnsiChar; + var targetStart: PWideChar; targetEnd: PWideChar): Integer; +var + target: PWideChar { Register }; + source: PAnsiChar { Register }; + BITbuffer: Cardinal { & "Address Of" Used }; + bufferbits: Integer { & "Address Of" Used }; + shifted: Boolean { Used In Boolean Context }; + first: Boolean { Used In Boolean Context }; + wroteone: Boolean; + base64EOF: Boolean; + base64value: Integer; + done: Boolean; + c: UCS2; + prevc: UCS2; + junk: UCS2 { Used In Boolean Context }; +begin + Initialize_UTF7_Data; + Result := 0; + BITbuffer := 0; + bufferbits := 0; + shifted := False; + first := False; + wroteone := False; + source := sourceStart; + target := targetStart; + c := 0; + if needtables then + tabinit; + repeat + { read an ASCII character c } + done := Source >= SourceEnd; + if (not done) then + begin + c := Word(Source^); + Inc(Source); + end { If }; + if shifted then + begin + { We're done with a base64 string if we hit EOF, it's not a valid } + { ASCII character, or it's not in the base64 set. } + { } + base64value := invbase64[c]; + base64EOF := (done or (c > $7F)) or (base64value < 0); + if base64EOF then + begin + shifted := False; + { If the character causing us to drop out was SHIFT_IN or } + { SHIFT_OUT, it may be a special escape for SHIFT_IN. The } + { test for SHIFT_IN is not necessary, but allows an alternate } + { form of UTF-7 where SHIFT_IN is escaped by SHIFT_IN. This } + { only works for some values of SHIFT_IN. } + { } + if ((not done) and ((c = Integer('+')) or (c = Integer('-')))) then + begin + { get another character c } + prevc := c; + Done := Source >= SourceEnd; + if (not Done) then + begin + c := Word(Source^); + Inc(Source); + { If no base64 characters were encountered, and the } + { character terminating the shift sequence was } + { SHIFT_OUT, then it's a special escape for SHIFT_IN. } + { } + end; + if first and (prevc = Integer('-')) then + begin + { write SHIFT_IN unicode } + if (target >= targetEnd) then + begin + Result := 2; + break; + end { If }; + Target^ := WideChar('+'); + Inc(Target); + end + else + begin + if (not wroteone) then + begin + Result := 1; + end { If }; + end { Else }; + ; + end { If } + else + begin + if (not wroteone) then + begin + Result := 1; + end { If }; + end { Else }; + end { If } + else + begin + { Add another 6 bits of base64 to the bit buffer. } + WRITE_N_BITS(base64value, 6, BITbuffer, + bufferbits); + first := False; + end { Else }; + { Extract as many full 16 bit characters as possible from the } + { bit buffer. } + { } + while (bufferbits >= 16) and (target < targetEnd) do + begin + { write a unicode } + Target^ := WideChar(READ_N_BITS(16, BITbuffer, bufferbits)); + Inc(Target); + wroteone := True; + end { While }; + if (bufferbits >= 16) then + begin + if (target >= targetEnd) then + begin + Result := 2; + Break; + end; + end { If }; + if (base64EOF) then + begin + junk := READ_N_BITS(bufferbits, BITbuffer, bufferbits); + if (junk <> 0) then + begin + Result := 1; + end { If }; + end { If }; + end { If }; + if (not shifted) and (not done) then + begin + if (c = Integer('+')) then + begin + shifted := True; + first := True; + wroteone := False; + end { If } + else + begin + { It must be a directly encoded character. } + if (c > $7F) then + begin + Result := 1; + end { If }; + if (target >= targetEnd) then + begin + Result := 2; + break; + end { If }; + Target^ := WideChar(c); + Inc(Target); + end { Else }; + end { If }; + until (done); + sourceStart := source; + targetStart := target; +end; { ConvertUTF7toUCS2 } + + {*****************************************************************************} + { Thanks to Francisco Leong for providing the Pascal conversion of } + { ConvertUTF7.c (by David B. Goldsmith) } + {*****************************************************************************} + +resourcestring + SBufferOverflow = 'Buffer overflow'; + SInvalidUTF7 = 'Invalid UTF7'; + +function WideStringToUTF7(const W: WideString): AnsiString; +var + SourceStart, SourceEnd: PWideChar; + TargetStart, TargetEnd: PAnsiChar; +begin + if W = '' then + Result := '' + else + begin + SetLength(Result, Length(W) * 7); // Assume worst case + SourceStart := PWideChar(@W[1]); + SourceEnd := PWideChar(@W[Length(W)]) + 1; + TargetStart := PAnsiChar(@Result[1]); + TargetEnd := PAnsiChar(@Result[Length(Result)]) + 1; + if ConvertUCS2toUTF7(SourceStart, SourceEnd, TargetStart, + TargetEnd, True, False) <> 0 + then + raise ETntInternalError.Create(SBufferOverflow); + SetLength(Result, TargetStart - PAnsiChar(@Result[1])); + end; +end; + +function UTF7ToWideString(const S: AnsiString): WideString; +var + SourceStart, SourceEnd: PAnsiChar; + TargetStart, TargetEnd: PWideChar; +begin + if (S = '') then + Result := '' + else + begin + SetLength(Result, Length(S)); // Assume Worst case + SourceStart := PAnsiChar(@S[1]); + SourceEnd := PAnsiChar(@S[Length(S)]) + 1; + TargetStart := PWideChar(@Result[1]); + TargetEnd := PWideChar(@Result[Length(Result)]) + 1; + case ConvertUTF7toUCS2(SourceStart, SourceEnd, TargetStart, + TargetEnd) of + 1: raise ETntGeneralError.Create(SInvalidUTF7); + 2: raise ETntInternalError.Create(SBufferOverflow); + end; + SetLength(Result, TargetStart - PWideChar(@Result[1])); + end; +end; + +function StringToWideStringEx(const S: AnsiString; CodePage: Cardinal): WideString; +var + InputLength, + OutputLength: Integer; +begin + if CodePage = CP_UTF7 then + Result := UTF7ToWideString(S) // CP_UTF7 not supported on Windows 95 + else if CodePage = CP_UTF8 then + Result := UTF8ToWideString(S) // CP_UTF8 not supported on Windows 95 + else begin + InputLength := Length(S); + OutputLength := MultiByteToWideChar(CodePage, 0, PAnsiChar(S), InputLength, nil, 0); + SetLength(Result, OutputLength); + MultiByteToWideChar(CodePage, 0, PAnsiChar(S), InputLength, PWideChar(Result), OutputLength); + end; +end; + +function WideStringToStringEx(const WS: WideString; CodePage: Cardinal): AnsiString; +var + InputLength, + OutputLength: Integer; +begin + if CodePage = CP_UTF7 then + Result := WideStringToUTF7(WS) // CP_UTF7 not supported on Windows 95 + else if CodePage = CP_UTF8 then + Result := WideStringToUTF8(WS) // CP_UTF8 not supported on Windows 95 + else begin + InputLength := Length(WS); + OutputLength := WideCharToMultiByte(CodePage, 0, PWideChar(WS), InputLength, nil, 0, nil, nil); + SetLength(Result, OutputLength); + WideCharToMultiByte(CodePage, 0, PWideChar(WS), InputLength, PAnsiChar(Result), OutputLength, nil, nil); + end; +end; + +function UCS2ToWideString(const Value: AnsiString): WideString; +begin + if Length(Value) = 0 then + Result := '' + else + SetString(Result, PWideChar(@Value[1]), Length(Value) div SizeOf(WideChar)) +end; + +function WideStringToUCS2(const Value: WideString): AnsiString; +begin + if Length(Value) = 0 then + Result := '' + else + SetString(Result, PAnsiChar(@Value[1]), Length(Value) * SizeOf(WideChar)) +end; + +{ Windows.pas doesn't declare TranslateCharsetInfo() correctly. } +function TranslateCharsetInfo(lpSrc: PDWORD; var lpCs: TCharsetInfo; dwFlags: DWORD): BOOL; stdcall; external gdi32 name 'TranslateCharsetInfo'; + +function CharSetToCodePage(ciCharset: UINT): Cardinal; +var + C: TCharsetInfo; +begin + Win32Check(TranslateCharsetInfo(PDWORD(ciCharset), C, TCI_SRCCHARSET)); + Result := C.ciACP +end; + +function LCIDToCodePage(ALcid: LCID): Cardinal; +var + Buf: array[0..6] of AnsiChar; +begin + GetLocaleInfo(ALcid, LOCALE_IDefaultAnsiCodePage, Buf, 6); + Result := StrToIntDef(Buf, GetACP); +end; + +function KeyboardCodePage: Cardinal; +begin + Result := LCIDToCodePage(GetKeyboardLayout(0) and $FFFF); +end; + +function KeyUnicode(CharCode: Word): WideChar; +var + AChar: AnsiChar; +begin + // converts the given character (as it comes with a WM_CHAR message) into its + // corresponding Unicode character depending on the active keyboard layout + if CharCode <= Word(High(AnsiChar)) then begin + AChar := AnsiChar(CharCode); + MultiByteToWideChar(KeyboardCodePage, MB_USEGLYPHCHARS, @AChar, 1, @Result, 1); + end else + Result := WideChar(CharCode); +end; + +procedure StrSwapByteOrder(Str: PWideChar); +var + P: PWord; +begin + P := PWord(Str); + While (P^ <> 0) do begin + P^ := MakeWord(HiByte(P^), LoByte(P^)); + Inc(P); + end; +end; + +{$IFDEF USE_SYSTEM_OVERRIDES} + +//-------------------------------------------------------------------- +// LoadResString() +// +// This system function is used to retrieve a resourcestring and +// return the result as an AnsiString. If we believe that the result +// is only a temporary value, and that it will be immediately +// assigned to a WideString or a Variant, then we will save the +// Unicode result as well as a reference to the original Ansi string. +// WStrFromPCharLen() or VarFromLStr() will return this saved +// Unicode string if it appears to receive the most recent result +// of LoadResString. +//-------------------------------------------------------------------- + + + //=========================================================================================== + // + // function CodeMatchesPatternForUnicode(...); + // + // GIVEN: SomeWideString := SSomeResString; { WideString := resourcestring } + // + // Delphi will compile this statement into the following: + // ------------------------------------------------- + // TempAnsiString := LoadResString(@SSomeResString); + // LINE 1: lea edx,[SomeTempAnsiString] + // LINE 2: mov eax,[@SomeResString] + // LINE 3: call LoadResString + // + // WStrFromLStr(SomeWideString, TempAnsiString); { SomeWideString := TempAnsiString } + // LINE 4: mov edx,[SomeTempAnsiString] + // LINE 5: mov/lea eax [@SomeWideString] + // LINE 6: call @WStrFromLStr + // ------------------------------------------------- + // + // The order in which the parameters are prepared for WStrFromLStr (ie LINE 4 & 5) is + // reversed when assigning a non-temporary AnsiString to a WideString. + // + // This code, for example, results in LINE 4 and LINE 5 being swapped. + // + // SomeAnsiString := SSomeResString; + // SomeWideString := SomeAnsiString; + // + // Since we know the "signature" used by the compiler, we can detect this pattern. + // If we believe it is only temporary, we can save the Unicode results for later + // retrieval from WStrFromLStr. + // + // One final note: When assigning a resourcestring to a Variant, the same patterns exist. + //=========================================================================================== + +function CodeMatchesPatternForUnicode(PLine4: PAnsiChar): Boolean; +const + SIZEOF_OPCODE = 1 {byte}; + MOV_16_OPCODE = AnsiChar($8B); { we'll assume operand size is 16 bits } + MOV_32_OPCODE = AnsiChar($B8); { we'll assume operand size is 32 bits } + LEA_OPCODE = AnsiChar($8D); { operand size can be 16 or 40 bits } + CALL_OPCODE = AnsiChar($E8); { assumed operand size is 32 bits } + BREAK_OPCODE = AnsiChar($CC); {in a breakpoint} +var + PLine1: PAnsiChar; + PLine2: PAnsiChar; + PLine3: PAnsiChar; + DataSize: Integer; // bytes in first LEA operand +begin + Result := False; + + PLine3 := PLine4 - SizeOf(CALL_OPCODE) - 4; + PLine2 := PLine3 - SizeOf(MOV_32_OPCODE) - 4; + + // figure PLine1 and operand size + DataSize := 2; { try 16 bit operand for line 1 } + PLine1 := PLine2 - DataSize - SizeOf(LEA_OPCODE); + if (PLine1^ <> LEA_OPCODE) and (not (IsDebugging and (PLine1^ = BREAK_OPCODE))) then + begin + DataSize := 5; { try 40 bit operand for line 1 } + PLine1 := PLine2 - DataSize - SizeOf(LEA_OPCODE); + end; + if (PLine1^ = LEA_OPCODE) or (IsDebugging and (PLine1^ = BREAK_OPCODE)) then + begin + if CompareMem(PLine1 + SIZEOF_OPCODE, PLine4 + SIZEOF_OPCODE, DataSize) then + begin + // After this check, it seems to match the WideString <- (temp) AnsiString pattern + Result := True; // It is probably OK. (The side effects of being wrong aren't very bad.) + end; + end; +end; + +threadvar + PLastResString: PAnsiChar; + LastResStringValue: AnsiString; + LastWideResString: WideString; + +procedure FreeTntSystemThreadVars; +begin + LastResStringValue := ''; + LastWideResString := ''; +end; + +procedure Custom_System_EndThread(ExitCode: Integer); +begin + FreeTntSystemThreadVars; + {$IFDEF COMPILER_10_UP} + if Assigned(SystemThreadEndProc) then + SystemThreadEndProc(ExitCode); + {$ENDIF} + ExitThread(ExitCode); +end; + +function Custom_System_LoadResString(ResStringRec: PResStringRec): AnsiString; +var + ReturnAddr: Pointer; +begin + // get return address + asm + PUSH ECX + MOV ECX, [EBP + 4] + MOV ReturnAddr, ECX + POP ECX + end; + // check calling code pattern + if CodeMatchesPatternForUnicode(ReturnAddr) then begin + // result will probably be assigned to an intermediate AnsiString + // on its way to either a WideString or Variant. + LastWideResString := WideLoadResString(ResStringRec); + Result := LastWideResString; + LastResStringValue := Result; + if Result = '' then + PLastResString := nil + else + PLastResString := PAnsiChar(Result); + end else begin + // result will probably be assigned to an actual AnsiString variable. + PLastResString := nil; + Result := WideLoadResString(ResStringRec); + end; +end; + +//-------------------------------------------------------------------- +// WStrFromPCharLen() +// +// This system function is used to assign an AnsiString to a WideString. +// It has been modified to assign Unicode results from LoadResString. +// Another purpose of this function is to specify the code page. +//-------------------------------------------------------------------- + +procedure Custom_System_WStrFromPCharLen(var Dest: WideString; Source: PAnsiChar; Length: Integer); +var + DestLen: Integer; + Buffer: array[0..2047] of WideChar; + Local_PLastResString: Pointer; +begin + Local_PLastResString := PLastResString; + if (Local_PLastResString <> nil) + and (Local_PLastResString = Source) + and (System.Length(LastResStringValue) = Length) + and (LastResStringValue = Source) then begin + // use last unicode resource string + PLastResString := nil; { clear for further use } + Dest := LastWideResString; + end else begin + if Local_PLastResString <> nil then + PLastResString := nil; { clear for further use } + if Length <= 0 then + begin + Dest := ''; + Exit; + end; + if Length + 1 < High(Buffer) then + begin + DestLen := MultiByteToWideChar(DefaultSystemCodePage, 0, Source, Length, Buffer, + High(Buffer)); + if DestLen > 0 then + begin + SetLength(Dest, DestLen); + Move(Pointer(@Buffer[0])^, Pointer(Dest)^, DestLen * SizeOf(WideChar)); + Exit; + end; + end; + DestLen := (Length + 1); + SetLength(Dest, DestLen); // overallocate, trim later + DestLen := MultiByteToWideChar(DefaultSystemCodePage, 0, Source, Length, Pointer(Dest), + DestLen); + if DestLen < 0 then + DestLen := 0; + SetLength(Dest, DestLen); + end; +end; + +{$IFNDEF COMPILER_9_UP} + +//-------------------------------------------------------------------- +// LStrFromPWCharLen() +// +// This system function is used to assign an WideString to an AnsiString. +// It has not been modified from its original purpose other than to specify the code page. +//-------------------------------------------------------------------- + +procedure Custom_System_LStrFromPWCharLen(var Dest: AnsiString; Source: PWideChar; Length: Integer); +var + DestLen: Integer; + Buffer: array[0..4095] of AnsiChar; +begin + if Length <= 0 then + begin + Dest := ''; + Exit; + end; + if Length + 1 < (High(Buffer) div sizeof(WideChar)) then + begin + DestLen := WideCharToMultiByte(DefaultSystemCodePage, 0, Source, + Length, Buffer, High(Buffer), + nil, nil); + if DestLen >= 0 then + begin + SetLength(Dest, DestLen); + Move(Pointer(@Buffer[0])^, PAnsiChar(Dest)^, DestLen); + Exit; + end; + end; + + DestLen := (Length + 1) * sizeof(WideChar); + SetLength(Dest, DestLen); // overallocate, trim later + DestLen := WideCharToMultiByte(DefaultSystemCodePage, 0, Source, Length, Pointer(Dest), DestLen, + nil, nil); + if DestLen < 0 then + DestLen := 0; + SetLength(Dest, DestLen); +end; + +//-------------------------------------------------------------------- +// WStrToString() +// +// This system function is used to assign an WideString to an short string. +// It has not been modified from its original purpose other than to specify the code page. +//-------------------------------------------------------------------- + +procedure Custom_System_WStrToString(Dest: PShortString; const Source: WideString; MaxLen: Integer); +var + SourceLen, DestLen: Integer; + Buffer: array[0..511] of AnsiChar; +begin + if MaxLen > 255 then MaxLen := 255; + SourceLen := Length(Source); + if SourceLen >= MaxLen then SourceLen := MaxLen; + if SourceLen = 0 then + DestLen := 0 + else begin + DestLen := WideCharToMultiByte(DefaultSystemCodePage, 0, Pointer(Source), SourceLen, + Buffer, SizeOf(Buffer), nil, nil); + if DestLen > MaxLen then DestLen := MaxLen; + end; + Dest^[0] := Chr(DestLen); + if DestLen > 0 then Move(Buffer, Dest^[1], DestLen); +end; + +{$ENDIF} + +//-------------------------------------------------------------------- +// VarFromLStr() +// +// This system function is used to assign an AnsiString to a Variant. +// It has been modified to assign Unicode results from LoadResString. +//-------------------------------------------------------------------- + +procedure Custom_System_VarFromLStr(var V: TVarData; const Value: AnsiString); +const + varDeepData = $BFE8; +var + Local_PLastResString: Pointer; +begin + if (V.VType and varDeepData) <> 0 then + VarClear(PVariant(@V)^); + + Local_PLastResString := PLastResString; + if (Local_PLastResString <> nil) + and (Local_PLastResString = PAnsiChar(Value)) + and (LastResStringValue = Value) then begin + // use last unicode resource string + PLastResString := nil; { clear for further use } + V.VOleStr := nil; + V.VType := varOleStr; + WideString(Pointer(V.VOleStr)) := Copy(LastWideResString, 1, MaxInt); + end else begin + if Local_PLastResString <> nil then + PLastResString := nil; { clear for further use } + V.VString := nil; + V.VType := varString; + AnsiString(V.VString) := Value; + end; +end; + +{$IFNDEF COMPILER_9_UP} + +//-------------------------------------------------------------------- +// WStrCat3() A := B + C; +// +// This system function is used to concatenate two strings into one result. +// This function is added because A := '' + '' doesn't necessarily result in A = ''; +//-------------------------------------------------------------------- + +procedure Custom_System_WStrCat3(var Dest: WideString; const Source1, Source2: WideString); + + function NewWideString(CharLength: Longint): Pointer; + var + _NewWideString: function(CharLength: Longint): Pointer; + begin + asm + PUSH ECX + MOV ECX, offset System.@NewWideString; + MOV _NewWideString, ECX + POP ECX + end; + Result := _NewWideString(CharLength); + end; + + procedure WStrSet(var S: WideString; P: PWideChar); + var + Temp: Pointer; + begin + Temp := Pointer(InterlockedExchange(Integer(S), Integer(P))); + if Temp <> nil then + WideString(Temp) := ''; + end; + +var + Source1Len, Source2Len: Integer; + NewStr: PWideChar; +begin + Source1Len := Length(Source1); + Source2Len := Length(Source2); + if (Source1Len <> 0) or (Source2Len <> 0) then + begin + NewStr := NewWideString(Source1Len + Source2Len); + Move(Pointer(Source1)^, Pointer(NewStr)^, Source1Len * sizeof(WideChar)); + Move(Pointer(Source2)^, NewStr[Source1Len], Source2Len * sizeof(WideChar)); + WStrSet(Dest, NewStr); + end else + Dest := ''; +end; + +{$ENDIF} + +//-------------------------------------------------------------------- +// System proc replacements +//-------------------------------------------------------------------- + +type + POverwrittenData = ^TOverwrittenData; + TOverwrittenData = record + Location: Pointer; + OldCode: array[0..6] of Byte; + end; + +procedure OverwriteProcedure(OldProcedure, NewProcedure: pointer; Data: POverwrittenData = nil); +{ OverwriteProcedure originally from Igor Siticov } +{ Modified by Jacques Garcia Vazquez } +var + x: PAnsiChar; + y: integer; + ov2, ov: cardinal; + p: pointer; +begin + if Assigned(Data) and (Data.Location <> nil) then + exit; { procedure already overwritten } + + // need six bytes in place of 5 + x := PAnsiChar(OldProcedure); + if not VirtualProtect(Pointer(x), 6, PAGE_EXECUTE_READWRITE, @ov) then + RaiseLastOSError; + + // if a jump is present then a redirect is found + // $FF25 = jmp dword ptr [xxx] + // This redirect is normally present in bpl files, but not in exe files + p := OldProcedure; + + if Word(p^) = $25FF then + begin + Inc(Integer(p), 2); // skip the jump + // get the jump address p^ and dereference it p^^ + p := Pointer(Pointer(p^)^); + + // release the memory + if not VirtualProtect(Pointer(x), 6, ov, @ov2) then + RaiseLastOSError; + + // re protect the correct one + x := PAnsiChar(p); + if not VirtualProtect(Pointer(x), 6, PAGE_EXECUTE_READWRITE, @ov) then + RaiseLastOSError; + end; + + if Assigned(Data) then + begin + Move(x^, Data.OldCode, 6); + { Assign Location last so that Location <> nil only if OldCode is properly initialized. } + Data.Location := x; + end; + + x[0] := AnsiChar($E9); + y := integer(NewProcedure) - integer(p) - 5; + x[1] := AnsiChar(y and 255); + x[2] := AnsiChar((y shr 8) and 255); + x[3] := AnsiChar((y shr 16) and 255); + x[4] := AnsiChar((y shr 24) and 255); + + if not VirtualProtect(Pointer(x), 6, ov, @ov2) then + RaiseLastOSError; +end; + +procedure RestoreProcedure(OriginalProc: Pointer; Data: TOverwrittenData); +var + ov, ov2: Cardinal; +begin + if Data.Location <> nil then begin + if not VirtualProtect(Data.Location, 6, PAGE_EXECUTE_READWRITE, @ov) then + RaiseLastOSError; + Move(Data.OldCode, Data.Location^, 6); + if not VirtualProtect(Data.Location, 6, ov, @ov2) then + RaiseLastOSError; + end; +end; + +function Addr_System_EndThread: Pointer; +begin + Result := @System.EndThread; +end; + +function Addr_System_LoadResString: Pointer; +begin + Result := @System.LoadResString{TNT-ALLOW LoadResString}; +end; + +function Addr_System_WStrFromPCharLen: Pointer; +asm + mov eax, offset System.@WStrFromPCharLen; +end; + +{$IFNDEF COMPILER_9_UP} +function Addr_System_LStrFromPWCharLen: Pointer; +asm + mov eax, offset System.@LStrFromPWCharLen; +end; + +function Addr_System_WStrToString: Pointer; +asm + mov eax, offset System.@WStrToString; +end; +{$ENDIF} + +function Addr_System_VarFromLStr: Pointer; +asm + mov eax, offset System.@VarFromLStr; +end; + +function Addr_System_WStrCat3: Pointer; +asm + mov eax, offset System.@WStrCat3; +end; + +var + System_EndThread_Code, + System_LoadResString_Code, + System_WStrFromPCharLen_Code, + {$IFNDEF COMPILER_9_UP} + System_LStrFromPWCharLen_Code, + System_WStrToString_Code, + {$ENDIF} + System_VarFromLStr_Code + {$IFNDEF COMPILER_9_UP} + , + System_WStrCat3_Code, + SysUtils_WideFmtStr_Code + {$ENDIF} + : TOverwrittenData; + +procedure InstallEndThreadOverride; +begin + OverwriteProcedure(Addr_System_EndThread, @Custom_System_EndThread, @System_EndThread_Code); +end; + +procedure InstallStringConversionOverrides; +begin + OverwriteProcedure(Addr_System_WStrFromPCharLen, @Custom_System_WStrFromPCharLen, @System_WStrFromPCharLen_Code); + {$IFNDEF COMPILER_9_UP} + OverwriteProcedure(Addr_System_LStrFromPWCharLen, @Custom_System_LStrFromPWCharLen, @System_LStrFromPWCharLen_Code); + OverwriteProcedure(Addr_System_WStrToString, @Custom_System_WStrToString, @System_WStrToString_Code); + {$ENDIF} +end; + +procedure InstallWideResourceStrings; +begin + OverwriteProcedure(Addr_System_LoadResString, @Custom_System_LoadResString, @System_LoadResString_Code); + OverwriteProcedure(Addr_System_VarFromLStr, @Custom_System_VarFromLStr, @System_VarFromLStr_Code); +end; + +{$IFNDEF COMPILER_9_UP} +procedure InstallWideStringConcatenationFix; +begin + OverwriteProcedure(Addr_System_WStrCat3, @Custom_System_WStrCat3, @System_WStrCat3_Code); +end; + +procedure InstallWideFormatFixes; +begin + OverwriteProcedure(@SysUtils.WideFmtStr, @TntSysUtils.Tnt_WideFmtStr, @SysUtils_WideFmtStr_Code); +end; +{$ENDIF} + +procedure InstallTntSystemUpdates(Updates: TTntSystemUpdateSet = AllTntSystemUpdates); +begin + InstallEndThreadOverride; + if tsWideResourceStrings in Updates then begin + InstallStringConversionOverrides; + InstallWideResourceStrings; + end; + {$IFNDEF COMPILER_9_UP} + if tsFixImplicitCodePage in Updates then begin + InstallStringConversionOverrides; + { CP_ACP is the code page used by the non-Unicode Windows API. } + GDefaultSystemCodePage := CP_ACP{TNT-ALLOW CP_ACP}; + end; + if tsFixWideStrConcat in Updates then begin + InstallWideStringConcatenationFix; + end; + if tsFixWideFormat in Updates then begin + InstallWideFormatFixes; + end; + {$ENDIF} +end; + +{$IFNDEF COMPILER_9_UP} +var + StartupDefaultUserCodePage: Cardinal; +{$ENDIF} + +procedure UninstallSystemOverrides; +begin + RestoreProcedure(Addr_System_EndThread, System_EndThread_Code); + // String Conversion + RestoreProcedure(Addr_System_WStrFromPCharLen, System_WStrFromPCharLen_Code); + {$IFNDEF COMPILER_9_UP} + RestoreProcedure(Addr_System_LStrFromPWCharLen, System_LStrFromPWCharLen_Code); + RestoreProcedure(Addr_System_WStrToString, System_WStrToString_Code); + GDefaultSystemCodePage := StartupDefaultUserCodePage; + {$ENDIF} + // Wide resourcestring + RestoreProcedure(Addr_System_LoadResString, System_LoadResString_Code); + RestoreProcedure(Addr_System_VarFromLStr, System_VarFromLStr_Code); + {$IFNDEF COMPILER_9_UP} + // WideString concat fix + RestoreProcedure(Addr_System_WStrCat3, System_WStrCat3_Code); + // WideFormat fixes + RestoreProcedure(@SysUtils.WideFmtStr, SysUtils_WideFmtStr_Code); + {$ENDIF} +end; + +{$ENDIF USE_SYSTEM_OVERRIDES} + +initialization + {$IFDEF COMPILER_9_UP} + {$DEFINE USE_GETACP} + {$ENDIF} + {$IFDEF FPC} + {$DEFINE USE_GETACP} + {$ENDIF} + {$IFDEF USE_GETACP} + GDefaultSystemCodePage := GetACP; + {$ELSE} + {$IFDEF COMPILER_7_UP} + if (Win32Platform = VER_PLATFORM_WIN32_NT) and (Win32MajorVersion >= 5) then + GDefaultSystemCodePage := CP_THREAD_ACP // Win 2K/XP/... + else + GDefaultSystemCodePage := LCIDToCodePage(GetThreadLocale); // Win NT4/95/98/ME + {$ELSE} + GDefaultSystemCodePage := CP_ACP{TNT-ALLOW CP_ACP}; + {$ENDIF} + {$ENDIF} + {$IFDEF USE_SYSTEM_OVERRIDES} + {$IFNDEF COMPILER_9_UP} + StartupDefaultUserCodePage := DefaultSystemCodePage; + {$ENDIF} + IsDebugging := DebugHook > 0; + {$ENDIF USE_SYSTEM_OVERRIDES} + +finalization + {$IFDEF USE_SYSTEM_OVERRIDES} + UninstallSystemOverrides; + FreeTntSystemThreadVars; { Make MemorySleuth happy. } + {$ENDIF USE_SYSTEM_OVERRIDES} + +end. diff --git a/cmake/src/lib/TntUnicodeControls/TntWideStrUtils.pas b/cmake/src/lib/TntUnicodeControls/TntWideStrUtils.pas new file mode 100644 index 00000000..99f63aea --- /dev/null +++ b/cmake/src/lib/TntUnicodeControls/TntWideStrUtils.pas @@ -0,0 +1,455 @@ + +{*****************************************************************************} +{ } +{ Tnt Delphi Unicode Controls } +{ http://www.tntware.com/delphicontrols/unicode/ } +{ Version: 2.3.0 } +{ } +{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } +{ } +{*****************************************************************************} + +unit TntWideStrUtils; + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +{$INCLUDE TntCompilers.inc} + +interface + +{ Wide string manipulation functions } + +{$IFNDEF COMPILER_9_UP} +function WStrAlloc(Size: Cardinal): PWideChar; +function WStrBufSize(const Str: PWideChar): Cardinal; +{$ENDIF} +{$IFNDEF COMPILER_10_UP} +function WStrMove(Dest: PWideChar; const Source: PWideChar; Count: Cardinal): PWideChar; +{$ENDIF} +{$IFNDEF COMPILER_9_UP} +function WStrNew(const Str: PWideChar): PWideChar; +procedure WStrDispose(Str: PWideChar); +{$ENDIF} +//--------------------------------------------------------------------------------------------- +{$IFNDEF COMPILER_9_UP} +function WStrLen(Str: PWideChar): Cardinal; +function WStrEnd(Str: PWideChar): PWideChar; +{$ENDIF} +{$IFNDEF COMPILER_10_UP} +function WStrCat(Dest: PWideChar; const Source: PWideChar): PWideChar; +{$ENDIF} +{$IFNDEF COMPILER_9_UP} +function WStrCopy(Dest, Source: PWideChar): PWideChar; +function WStrLCopy(Dest, Source: PWideChar; MaxLen: Cardinal): PWideChar; +function WStrPCopy(Dest: PWideChar; const Source: WideString): PWideChar; +function WStrPLCopy(Dest: PWideChar; const Source: WideString; MaxLen: Cardinal): PWideChar; +{$ENDIF} +{$IFNDEF COMPILER_10_UP} +function WStrScan(const Str: PWideChar; Chr: WideChar): PWideChar; +// WStrComp and WStrPos were introduced as broken in Delphi 2006, but fixed in Delphi 2006 Update 2 +function WStrComp(Str1, Str2: PWideChar): Integer; +function WStrPos(Str, SubStr: PWideChar): PWideChar; +{$ENDIF} +function Tnt_WStrComp(Str1, Str2: PWideChar): Integer; deprecated; +function Tnt_WStrPos(Str, SubStr: PWideChar): PWideChar; deprecated; + +{ ------------ introduced --------------- } +function WStrECopy(Dest, Source: PWideChar): PWideChar; +function WStrLComp(Str1, Str2: PWideChar; MaxLen: Cardinal): Integer; +function WStrLIComp(Str1, Str2: PWideChar; MaxLen: Cardinal): Integer; +function WStrIComp(Str1, Str2: PWideChar): Integer; +function WStrLower(Str: PWideChar): PWideChar; +function WStrUpper(Str: PWideChar): PWideChar; +function WStrRScan(const Str: PWideChar; Chr: WideChar): PWideChar; +function WStrLCat(Dest: PWideChar; const Source: PWideChar; MaxLen: Cardinal): PWideChar; +function WStrPas(const Str: PWideChar): WideString; + +{ SysUtils.pas } //------------------------------------------------------------------------- + +{$IFNDEF COMPILER_10_UP} +function WideLastChar(const S: WideString): PWideChar; +function WideQuotedStr(const S: WideString; Quote: WideChar): WideString; +{$ENDIF} +{$IFNDEF COMPILER_9_UP} +function WideExtractQuotedStr(var Src: PWideChar; Quote: WideChar): Widestring; +{$ENDIF} +{$IFNDEF COMPILER_10_UP} +function WideDequotedStr(const S: WideString; AQuote: WideChar): WideString; +{$ENDIF} + +implementation + +uses + {$IFDEF COMPILER_9_UP} WideStrUtils, {$ENDIF} Math, Windows, TntWindows; + +{$IFNDEF COMPILER_9_UP} +function WStrAlloc(Size: Cardinal): PWideChar; +begin + Size := SizeOf(Cardinal) + (Size * SizeOf(WideChar)); + GetMem(Result, Size); + PCardinal(Result)^ := Size; + Inc(PAnsiChar(Result), SizeOf(Cardinal)); +end; + +function WStrBufSize(const Str: PWideChar): Cardinal; +var + P: PWideChar; +begin + P := Str; + Dec(PAnsiChar(P), SizeOf(Cardinal)); + Result := PCardinal(P)^ - SizeOf(Cardinal); + Result := Result div SizeOf(WideChar); +end; +{$ENDIF} + +{$IFNDEF COMPILER_10_UP} +function WStrMove(Dest: PWideChar; const Source: PWideChar; Count: Cardinal): PWideChar; +var + Length: Integer; +begin + Result := Dest; + Length := Count * SizeOf(WideChar); + Move(Source^, Dest^, Length); +end; +{$ENDIF} + +{$IFNDEF COMPILER_9_UP} +function WStrNew(const Str: PWideChar): PWideChar; +var + Size: Cardinal; +begin + if Str = nil then Result := nil else + begin + Size := WStrLen(Str) + 1; + Result := WStrMove(WStrAlloc(Size), Str, Size); + end; +end; + +procedure WStrDispose(Str: PWideChar); +begin + if Str <> nil then + begin + Dec(PAnsiChar(Str), SizeOf(Cardinal)); + FreeMem(Str, Cardinal(Pointer(Str)^)); + end; +end; +{$ENDIF} + +//--------------------------------------------------------------------------------------------- + +{$IFNDEF COMPILER_9_UP} +function WStrLen(Str: PWideChar): Cardinal; +begin + Result := WStrEnd(Str) - Str; +end; + +function WStrEnd(Str: PWideChar): PWideChar; +begin + // returns a pointer to the end of a null terminated string + Result := Str; + While Result^ <> #0 do + Inc(Result); +end; +{$ENDIF} + +{$IFNDEF COMPILER_10_UP} +function WStrCat(Dest: PWideChar; const Source: PWideChar): PWideChar; +begin + Result := Dest; + WStrCopy(WStrEnd(Dest), Source); +end; +{$ENDIF} + +{$IFNDEF COMPILER_9_UP} +function WStrCopy(Dest, Source: PWideChar): PWideChar; +begin + Result := WStrLCopy(Dest, Source, MaxInt); +end; + +function WStrLCopy(Dest, Source: PWideChar; MaxLen: Cardinal): PWideChar; +var + Count: Cardinal; +begin + // copies a specified maximum number of characters from Source to Dest + Result := Dest; + Count := 0; + While (Count < MaxLen) and (Source^ <> #0) do begin + Dest^ := Source^; + Inc(Source); + Inc(Dest); + Inc(Count); + end; + Dest^ := #0; +end; + +function WStrPCopy(Dest: PWideChar; const Source: WideString): PWideChar; +begin + Result := WStrLCopy(Dest, PWideChar(Source), Length(Source)); +end; + +function WStrPLCopy(Dest: PWideChar; const Source: WideString; MaxLen: Cardinal): PWideChar; +begin + Result := WStrLCopy(Dest, PWideChar(Source), MaxLen); +end; +{$ENDIF} + +{$IFNDEF COMPILER_10_UP} +function WStrScan(const Str: PWideChar; Chr: WideChar): PWideChar; +begin + Result := Str; + while Result^ <> Chr do + begin + if Result^ = #0 then + begin + Result := nil; + Exit; + end; + Inc(Result); + end; +end; + +function WStrComp(Str1, Str2: PWideChar): Integer; +begin + Result := WStrLComp(Str1, Str2, MaxInt); +end; + +function WStrPos(Str, SubStr: PWideChar): PWideChar; +var + PSave: PWideChar; + P: PWideChar; + PSub: PWideChar; +begin + // returns a pointer to the first occurance of SubStr in Str + Result := nil; + if (Str <> nil) and (Str^ <> #0) and (SubStr <> nil) and (SubStr^ <> #0) then begin + P := Str; + While P^ <> #0 do begin + if P^ = SubStr^ then begin + // investigate possibility here + PSave := P; + PSub := SubStr; + While (P^ = PSub^) do begin + Inc(P); + Inc(PSub); + if (PSub^ = #0) then begin + Result := PSave; + exit; // found a match + end; + if (P^ = #0) then + exit; // no match, hit end of string + end; + P := PSave; + end; + Inc(P); + end; + end; +end; +{$ENDIF} + +function Tnt_WStrComp(Str1, Str2: PWideChar): Integer; deprecated; +begin + Result := WStrComp(Str1, Str2); +end; + +function Tnt_WStrPos(Str, SubStr: PWideChar): PWideChar; deprecated; +begin + Result := WStrPos(Str, SubStr); +end; + +//------------------------------------------------------------------------------ + +function WStrECopy(Dest, Source: PWideChar): PWideChar; +begin + Result := WStrEnd(WStrCopy(Dest, Source)); +end; + +function WStrComp_EX(Str1, Str2: PWideChar; MaxLen: Cardinal; dwCmpFlags: Cardinal): Integer; +var + Len1, Len2: Integer; +begin + if MaxLen = Cardinal(MaxInt) then begin + Len1 := -1; + Len2 := -1; + end else begin + Len1 := Min(WStrLen(Str1), MaxLen); + Len2 := Min(WStrLen(Str2), MaxLen); + end; + Result := Tnt_CompareStringW(GetThreadLocale, dwCmpFlags, Str1, Len1, Str2, Len2) - 2; +end; + +function WStrLComp(Str1, Str2: PWideChar; MaxLen: Cardinal): Integer; +begin + Result := WStrComp_EX(Str1, Str2, MaxLen, 0); +end; + +function WStrLIComp(Str1, Str2: PWideChar; MaxLen: Cardinal): Integer; +begin + Result := WStrComp_EX(Str1, Str2, MaxLen, NORM_IGNORECASE); +end; + +function WStrIComp(Str1, Str2: PWideChar): Integer; +begin + Result := WStrLIComp(Str1, Str2, MaxInt); +end; + +function WStrLower(Str: PWideChar): PWideChar; +begin + Result := Str; + Tnt_CharLowerBuffW(Str, WStrLen(Str)) +end; + +function WStrUpper(Str: PWideChar): PWideChar; +begin + Result := Str; + Tnt_CharUpperBuffW(Str, WStrLen(Str)) +end; + +function WStrRScan(const Str: PWideChar; Chr: WideChar): PWideChar; +var + MostRecentFound: PWideChar; +begin + if Chr = #0 then + Result := WStrEnd(Str) + else + begin + Result := nil; + MostRecentFound := Str; + while True do + begin + while MostRecentFound^ <> Chr do + begin + if MostRecentFound^ = #0 then + Exit; + Inc(MostRecentFound); + end; + Result := MostRecentFound; + Inc(MostRecentFound); + end; + end; +end; + +function WStrLCat(Dest: PWideChar; const Source: PWideChar; MaxLen: Cardinal): PWideChar; +begin + Result := Dest; + WStrLCopy(WStrEnd(Dest), Source, MaxLen - WStrLen(Dest)); +end; + +function WStrPas(const Str: PWideChar): WideString; +begin + Result := Str; +end; + +//--------------------------------------------------------------------------------------------- + +{$IFNDEF COMPILER_10_UP} +function WideLastChar(const S: WideString): PWideChar; +begin + if S = '' then + Result := nil + else + Result := @S[Length(S)]; +end; + +function WideQuotedStr(const S: WideString; Quote: WideChar): WideString; +var + P, Src, + Dest: PWideChar; + AddCount: Integer; +begin + AddCount := 0; + P := WStrScan(PWideChar(S), Quote); + while (P <> nil) do + begin + Inc(P); + Inc(AddCount); + P := WStrScan(P, Quote); + end; + + if AddCount = 0 then + Result := Quote + S + Quote + else + begin + SetLength(Result, Length(S) + AddCount + 2); + Dest := PWideChar(Result); + Dest^ := Quote; + Inc(Dest); + Src := PWideChar(S); + P := WStrScan(Src, Quote); + repeat + Inc(P); + Move(Src^, Dest^, 2 * (P - Src)); + Inc(Dest, P - Src); + Dest^ := Quote; + Inc(Dest); + Src := P; + P := WStrScan(Src, Quote); + until P = nil; + P := WStrEnd(Src); + Move(Src^, Dest^, 2 * (P - Src)); + Inc(Dest, P - Src); + Dest^ := Quote; + end; +end; +{$ENDIF} + +{$IFNDEF COMPILER_9_UP} +function WideExtractQuotedStr(var Src: PWideChar; Quote: WideChar): Widestring; +var + P, Dest: PWideChar; + DropCount: Integer; +begin + Result := ''; + if (Src = nil) or (Src^ <> Quote) then Exit; + Inc(Src); + DropCount := 1; + P := Src; + Src := WStrScan(Src, Quote); + while Src <> nil do // count adjacent pairs of quote chars + begin + Inc(Src); + if Src^ <> Quote then Break; + Inc(Src); + Inc(DropCount); + Src := WStrScan(Src, Quote); + end; + if Src = nil then Src := WStrEnd(P); + if ((Src - P) <= 1) then Exit; + if DropCount = 1 then + SetString(Result, P, Src - P - 1) + else + begin + SetLength(Result, Src - P - DropCount); + Dest := PWideChar(Result); + Src := WStrScan(P, Quote); + while Src <> nil do + begin + Inc(Src); + if Src^ <> Quote then Break; + Move(P^, Dest^, (Src - P) * SizeOf(WideChar)); + Inc(Dest, Src - P); + Inc(Src); + P := Src; + Src := WStrScan(Src, Quote); + end; + if Src = nil then Src := WStrEnd(P); + Move(P^, Dest^, (Src - P - 1) * SizeOf(WideChar)); + end; +end; +{$ENDIF} + +{$IFNDEF COMPILER_10_UP} +function WideDequotedStr(const S: WideString; AQuote: WideChar): WideString; +var + LText : PWideChar; +begin + LText := PWideChar(S); + Result := WideExtractQuotedStr(LText, AQuote); + if Result = '' then + Result := S; +end; +{$ENDIF} + + +end. diff --git a/cmake/src/lib/TntUnicodeControls/TntWideStrings.pas b/cmake/src/lib/TntUnicodeControls/TntWideStrings.pas new file mode 100644 index 00000000..75132d22 --- /dev/null +++ b/cmake/src/lib/TntUnicodeControls/TntWideStrings.pas @@ -0,0 +1,846 @@ + +{*****************************************************************************} +{ } +{ Tnt Delphi Unicode Controls } +{ http://www.tntware.com/delphicontrols/unicode/ } +{ Version: 2.3.0 } +{ } +{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } +{ } +{*****************************************************************************} + +unit TntWideStrings; + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +{$INCLUDE TntCompilers.inc} + +interface + +{$IFDEF COMPILER_10_UP} + {$MESSAGE FATAL 'Do not refer to TntWideStrings.pas. It works correctly in Delphi 2006.'} +{$ENDIF} + +uses + Classes; + +{******************************************************************************} +{ } +{ Delphi 2005 introduced TWideStrings in WideStrings.pas. } +{ Unfortunately, it was not ready for prime time. } +{ Setting CommaText is not consistent, and it relies on CharNextW } +{ Which is only available on Windows NT+. } +{ } +{******************************************************************************} + +type + TWideStrings = class; + +{ IWideStringsAdapter interface } +{ Maintains link between TWideStrings and IWideStrings implementations } + + IWideStringsAdapter = interface + ['{25FE0E3B-66CB-48AA-B23B-BCFA67E8F5DA}'] + procedure ReferenceStrings(S: TWideStrings); + procedure ReleaseStrings; + end; + + TWideStringsEnumerator = class + private + FIndex: Integer; + FStrings: TWideStrings; + public + constructor Create(AStrings: TWideStrings); + function GetCurrent: WideString; + function MoveNext: Boolean; + property Current: WideString read GetCurrent; + end; + +{$IFDEF FPC} + TStringsDefined = set of ( + sdDelimiter, sdQuoteChar, sdNameValueSeparator, sdLineBreak, + sdStrictDelimiter); +{$ENDIF} + +{$DEFINE NAMEVALUESEPARATOR_RW} +{$IFNDEF COMPILER_7_UP} + {$UNDEF NAMEVALUESEPARATOR_RW} +{$ENDIF} + +{ TWideStrings class } + + TWideStrings = class(TPersistent) + private + FDefined: TStringsDefined; + FDelimiter: WideChar; + FQuoteChar: WideChar; + {$IFDEF NAMEVALUESEPARATOR_RW} + FNameValueSeparator: WideChar; + {$ENDIF} + FUpdateCount: Integer; + FAdapter: IWideStringsAdapter; + function GetCommaText: WideString; + function GetDelimitedText: WideString; + function GetName(Index: Integer): WideString; + function GetValue(const Name: WideString): WideString; + procedure ReadData(Reader: TReader); + procedure SetCommaText(const Value: WideString); + procedure SetDelimitedText(const Value: WideString); + procedure SetStringsAdapter(const Value: IWideStringsAdapter); + procedure SetValue(const Name, Value: WideString); + procedure WriteData(Writer: TWriter); + function GetDelimiter: WideChar; + procedure SetDelimiter(const Value: WideChar); + function GetQuoteChar: WideChar; + procedure SetQuoteChar(const Value: WideChar); + function GetNameValueSeparator: WideChar; + {$IFDEF NAMEVALUESEPARATOR_RW} + procedure SetNameValueSeparator(const Value: WideChar); + {$ENDIF} + function GetValueFromIndex(Index: Integer): WideString; + procedure SetValueFromIndex(Index: Integer; const Value: WideString); + protected + procedure AssignTo(Dest: TPersistent); override; + procedure DefineProperties(Filer: TFiler); override; + procedure Error(const Msg: WideString; Data: Integer); overload; + procedure Error(Msg: PResStringRec; Data: Integer); overload; + function ExtractName(const S: WideString): WideString; + function Get(Index: Integer): WideString; virtual; abstract; + function GetCapacity: Integer; virtual; + function GetCount: Integer; virtual; abstract; + function GetObject(Index: Integer): TObject; virtual; + function GetTextStr: WideString; virtual; + procedure Put(Index: Integer; const S: WideString); virtual; + procedure PutObject(Index: Integer; AObject: TObject); virtual; + procedure SetCapacity(NewCapacity: Integer); virtual; + procedure SetTextStr(const Value: WideString); virtual; + procedure SetUpdateState(Updating: Boolean); virtual; + property UpdateCount: Integer read FUpdateCount; + function CompareStrings(const S1, S2: WideString): Integer; virtual; + public + destructor Destroy; override; + function Add(const S: WideString): Integer; virtual; + function AddObject(const S: WideString; AObject: TObject): Integer; virtual; + procedure Append(const S: WideString); + procedure AddStrings(Strings: TStrings{TNT-ALLOW TStrings}); overload; virtual; + procedure AddStrings(Strings: TWideStrings); overload; virtual; + procedure Assign(Source: TPersistent); override; + procedure BeginUpdate; + procedure Clear; virtual; abstract; + procedure Delete(Index: Integer); virtual; abstract; + procedure EndUpdate; + function Equals(Strings: TWideStrings): Boolean; + procedure Exchange(Index1, Index2: Integer); virtual; + function GetEnumerator: TWideStringsEnumerator; + function GetTextW: PWideChar; virtual; + function IndexOf(const S: WideString): Integer; virtual; + function IndexOfName(const Name: WideString): Integer; virtual; + function IndexOfObject(AObject: TObject): Integer; virtual; + procedure Insert(Index: Integer; const S: WideString); virtual; abstract; + procedure InsertObject(Index: Integer; const S: WideString; + AObject: TObject); virtual; + procedure LoadFromFile(const FileName: WideString); virtual; + procedure LoadFromStream(Stream: TStream); virtual; + procedure Move(CurIndex, NewIndex: Integer); virtual; + procedure SaveToFile(const FileName: WideString); virtual; + procedure SaveToStream(Stream: TStream); virtual; + procedure SetTextW(const Text: PWideChar); virtual; + property Capacity: Integer read GetCapacity write SetCapacity; + property CommaText: WideString read GetCommaText write SetCommaText; + property Count: Integer read GetCount; + property Delimiter: WideChar read GetDelimiter write SetDelimiter; + property DelimitedText: WideString read GetDelimitedText write SetDelimitedText; + property Names[Index: Integer]: WideString read GetName; + property Objects[Index: Integer]: TObject read GetObject write PutObject; + property QuoteChar: WideChar read GetQuoteChar write SetQuoteChar; + property Values[const Name: WideString]: WideString read GetValue write SetValue; + property ValueFromIndex[Index: Integer]: WideString read GetValueFromIndex write SetValueFromIndex; + property NameValueSeparator: WideChar read GetNameValueSeparator {$IFDEF NAMEVALUESEPARATOR_RW} write SetNameValueSeparator {$ENDIF}; + property Strings[Index: Integer]: WideString read Get write Put; default; + property Text: WideString read GetTextStr write SetTextStr; + property StringsAdapter: IWideStringsAdapter read FAdapter write SetStringsAdapter; + end; + + PWideStringItem = ^TWideStringItem; + TWideStringItem = record + FString: WideString; + FObject: TObject; + end; + + PWideStringItemList = ^TWideStringItemList; + TWideStringItemList = array[0..MaxListSize] of TWideStringItem; + +implementation + +uses + Windows, SysUtils, TntSystem, {$IFDEF COMPILER_9_UP} WideStrUtils, {$ELSE} TntWideStrUtils, {$ENDIF} + TntSysUtils, TntClasses; + +{ TWideStringsEnumerator } + +constructor TWideStringsEnumerator.Create(AStrings: TWideStrings); +begin + inherited Create; + FIndex := -1; + FStrings := AStrings; +end; + +function TWideStringsEnumerator.GetCurrent: WideString; +begin + Result := FStrings[FIndex]; +end; + +function TWideStringsEnumerator.MoveNext: Boolean; +begin + Result := FIndex < FStrings.Count - 1; + if Result then + Inc(FIndex); +end; + +{ TWideStrings } + +destructor TWideStrings.Destroy; +begin + StringsAdapter := nil; + inherited; +end; + +function TWideStrings.Add(const S: WideString): Integer; +begin + Result := GetCount; + Insert(Result, S); +end; + +function TWideStrings.AddObject(const S: WideString; AObject: TObject): Integer; +begin + Result := Add(S); + PutObject(Result, AObject); +end; + +procedure TWideStrings.Append(const S: WideString); +begin + Add(S); +end; + +procedure TWideStrings.AddStrings(Strings: TStrings{TNT-ALLOW TStrings}); +var + I: Integer; +begin + BeginUpdate; + try + for I := 0 to Strings.Count - 1 do + AddObject(Strings[I], Strings.Objects[I]); + finally + EndUpdate; + end; +end; + +procedure TWideStrings.AddStrings(Strings: TWideStrings); +var + I: Integer; +begin + BeginUpdate; + try + for I := 0 to Strings.Count - 1 do + AddObject(Strings[I], Strings.Objects[I]); + finally + EndUpdate; + end; +end; + +procedure TWideStrings.Assign(Source: TPersistent); +begin + if Source is TWideStrings then + begin + BeginUpdate; + try + Clear; + FDefined := TWideStrings(Source).FDefined; + {$IFDEF NAMEVALUESEPARATOR_RW} + FNameValueSeparator := TWideStrings(Source).FNameValueSeparator; + {$ENDIF} + FQuoteChar := TWideStrings(Source).FQuoteChar; + FDelimiter := TWideStrings(Source).FDelimiter; + AddStrings(TWideStrings(Source)); + finally + EndUpdate; + end; + end + else if Source is TStrings{TNT-ALLOW TStrings} then + begin + BeginUpdate; + try + Clear; + {$IFDEF NAMEVALUESEPARATOR_RW} + FNameValueSeparator := WideChar(TStrings{TNT-ALLOW TStrings}(Source).NameValueSeparator); + {$ENDIF} + FQuoteChar := WideChar(TStrings{TNT-ALLOW TStrings}(Source).QuoteChar); + FDelimiter := WideChar(TStrings{TNT-ALLOW TStrings}(Source).Delimiter); + AddStrings(TStrings{TNT-ALLOW TStrings}(Source)); + finally + EndUpdate; + end; + end + else + inherited Assign(Source); +end; + +procedure TWideStrings.AssignTo(Dest: TPersistent); +var + I: Integer; +begin + if Dest is TWideStrings then Dest.Assign(Self) + else if Dest is TStrings{TNT-ALLOW TStrings} then + begin + TStrings{TNT-ALLOW TStrings}(Dest).BeginUpdate; + try + TStrings{TNT-ALLOW TStrings}(Dest).Clear; + {$IFDEF NAMEVALUESEPARATOR_RW} + TStrings{TNT-ALLOW TStrings}(Dest).NameValueSeparator := AnsiChar(NameValueSeparator); + {$ENDIF} + TStrings{TNT-ALLOW TStrings}(Dest).QuoteChar := AnsiChar(QuoteChar); + TStrings{TNT-ALLOW TStrings}(Dest).Delimiter := AnsiChar(Delimiter); + for I := 0 to Count - 1 do + TStrings{TNT-ALLOW TStrings}(Dest).AddObject(Strings[I], Objects[I]); + finally + TStrings{TNT-ALLOW TStrings}(Dest).EndUpdate; + end; + end + else + inherited AssignTo(Dest); +end; + +procedure TWideStrings.BeginUpdate; +begin + if FUpdateCount = 0 then SetUpdateState(True); + Inc(FUpdateCount); +end; + +procedure TWideStrings.DefineProperties(Filer: TFiler); + + function DoWrite: Boolean; + begin + if Filer.Ancestor <> nil then + begin + Result := True; + if Filer.Ancestor is TWideStrings then + Result := not Equals(TWideStrings(Filer.Ancestor)) + end + else Result := Count > 0; + end; + +begin + Filer.DefineProperty('Strings', ReadData, WriteData, DoWrite); +end; + +procedure TWideStrings.EndUpdate; +begin + Dec(FUpdateCount); + if FUpdateCount = 0 then SetUpdateState(False); +end; + +function TWideStrings.Equals(Strings: TWideStrings): Boolean; +var + I, Count: Integer; +begin + Result := False; + Count := GetCount; + if Count <> Strings.GetCount then Exit; + for I := 0 to Count - 1 do if Get(I) <> Strings.Get(I) then Exit; + Result := True; +end; + +procedure TWideStrings.Error(const Msg: WideString; Data: Integer); + + function ReturnAddr: Pointer; + asm + MOV EAX,[EBP+4] + end; + +begin + raise EStringListError.CreateFmt(Msg, [Data]) at ReturnAddr; +end; + +procedure TWideStrings.Error(Msg: PResStringRec; Data: Integer); +begin + Error(WideLoadResString(Msg), Data); +end; + +procedure TWideStrings.Exchange(Index1, Index2: Integer); +var + TempObject: TObject; + TempString: WideString; +begin + BeginUpdate; + try + TempString := Strings[Index1]; + TempObject := Objects[Index1]; + Strings[Index1] := Strings[Index2]; + Objects[Index1] := Objects[Index2]; + Strings[Index2] := TempString; + Objects[Index2] := TempObject; + finally + EndUpdate; + end; +end; + +function TWideStrings.ExtractName(const S: WideString): WideString; +var + P: Integer; +begin + Result := S; + P := Pos(NameValueSeparator, Result); + if P <> 0 then + SetLength(Result, P-1) else + SetLength(Result, 0); +end; + +function TWideStrings.GetCapacity: Integer; +begin // descendents may optionally override/replace this default implementation + Result := Count; +end; + +function TWideStrings.GetCommaText: WideString; +var + LOldDefined: TStringsDefined; + LOldDelimiter: WideChar; + LOldQuoteChar: WideChar; +begin + LOldDefined := FDefined; + LOldDelimiter := FDelimiter; + LOldQuoteChar := FQuoteChar; + Delimiter := ','; + QuoteChar := '"'; + try + Result := GetDelimitedText; + finally + FDelimiter := LOldDelimiter; + FQuoteChar := LOldQuoteChar; + FDefined := LOldDefined; + end; +end; + +function TWideStrings.GetDelimitedText: WideString; +var + S: WideString; + P: PWideChar; + I, Count: Integer; +begin + Count := GetCount; + if (Count = 1) and (Get(0) = '') then + Result := WideString(QuoteChar) + QuoteChar + else + begin + Result := ''; + for I := 0 to Count - 1 do + begin + S := Get(I); + P := PWideChar(S); + while not ((P^ in [WideChar(#0)..WideChar(' ')]) or (P^ = QuoteChar) or (P^ = Delimiter)) do + Inc(P); + if (P^ <> #0) then S := WideQuotedStr(S, QuoteChar); + Result := Result + S + Delimiter; + end; + System.Delete(Result, Length(Result), 1); + end; +end; + +function TWideStrings.GetName(Index: Integer): WideString; +begin + Result := ExtractName(Get(Index)); +end; + +function TWideStrings.GetObject(Index: Integer): TObject; +begin + Result := nil; +end; + +function TWideStrings.GetEnumerator: TWideStringsEnumerator; +begin + Result := TWideStringsEnumerator.Create(Self); +end; + +function TWideStrings.GetTextW: PWideChar; +begin + Result := WStrNew(PWideChar(GetTextStr)); +end; + +function TWideStrings.GetTextStr: WideString; +var + I, L, Size, Count: Integer; + P: PWideChar; + S, LB: WideString; +begin + Count := GetCount; + Size := 0; + LB := sLineBreak; + for I := 0 to Count - 1 do Inc(Size, Length(Get(I)) + Length(LB)); + SetString(Result, nil, Size); + P := Pointer(Result); + for I := 0 to Count - 1 do + begin + S := Get(I); + L := Length(S); + if L <> 0 then + begin + System.Move(Pointer(S)^, P^, L * SizeOf(WideChar)); + Inc(P, L); + end; + L := Length(LB); + if L <> 0 then + begin + System.Move(Pointer(LB)^, P^, L * SizeOf(WideChar)); + Inc(P, L); + end; + end; +end; + +function TWideStrings.GetValue(const Name: WideString): WideString; +var + I: Integer; +begin + I := IndexOfName(Name); + if I >= 0 then + Result := Copy(Get(I), Length(Name) + 2, MaxInt) else + Result := ''; +end; + +function TWideStrings.IndexOf(const S: WideString): Integer; +begin + for Result := 0 to GetCount - 1 do + if CompareStrings(Get(Result), S) = 0 then Exit; + Result := -1; +end; + +function TWideStrings.IndexOfName(const Name: WideString): Integer; +var + P: Integer; + S: WideString; +begin + for Result := 0 to GetCount - 1 do + begin + S := Get(Result); + P := Pos(NameValueSeparator, S); + if (P <> 0) and (CompareStrings(Copy(S, 1, P - 1), Name) = 0) then Exit; + end; + Result := -1; +end; + +function TWideStrings.IndexOfObject(AObject: TObject): Integer; +begin + for Result := 0 to GetCount - 1 do + if GetObject(Result) = AObject then Exit; + Result := -1; +end; + +procedure TWideStrings.InsertObject(Index: Integer; const S: WideString; + AObject: TObject); +begin + Insert(Index, S); + PutObject(Index, AObject); +end; + +procedure TWideStrings.LoadFromFile(const FileName: WideString); +var + Stream: TStream; +begin + Stream := TTntFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite); + try + LoadFromStream(Stream); + finally + Stream.Free; + end; +end; + +procedure TWideStrings.LoadFromStream(Stream: TStream); +var + Size: Integer; + S: WideString; +begin + BeginUpdate; + try + Size := Stream.Size - Stream.Position; + SetString(S, nil, Size div SizeOf(WideChar)); + Stream.Read(Pointer(S)^, Length(S) * SizeOf(WideChar)); + SetTextStr(S); + finally + EndUpdate; + end; +end; + +procedure TWideStrings.Move(CurIndex, NewIndex: Integer); +var + TempObject: TObject; + TempString: WideString; +begin + if CurIndex <> NewIndex then + begin + BeginUpdate; + try + TempString := Get(CurIndex); + TempObject := GetObject(CurIndex); + Delete(CurIndex); + InsertObject(NewIndex, TempString, TempObject); + finally + EndUpdate; + end; + end; +end; + +procedure TWideStrings.Put(Index: Integer; const S: WideString); +var + TempObject: TObject; +begin + TempObject := GetObject(Index); + Delete(Index); + InsertObject(Index, S, TempObject); +end; + +procedure TWideStrings.PutObject(Index: Integer; AObject: TObject); +begin +end; + +procedure TWideStrings.ReadData(Reader: TReader); +begin + if Reader.NextValue in [vaString, vaLString] then + SetTextStr(Reader.ReadString) {JCL compatiblity} + else if Reader.NextValue = vaWString then + SetTextStr(Reader.ReadWideString) {JCL compatiblity} + else begin + BeginUpdate; + try + Clear; + Reader.ReadListBegin; + while not Reader.EndOfList do + if Reader.NextValue in [vaString, vaLString] then + Add(Reader.ReadString) {TStrings compatiblity} + else + Add(Reader.ReadWideString); + Reader.ReadListEnd; + finally + EndUpdate; + end; + end; +end; + +procedure TWideStrings.SaveToFile(const FileName: WideString); +var + Stream: TStream; +begin + Stream := TTntFileStream.Create(FileName, fmCreate); + try + SaveToStream(Stream); + finally + Stream.Free; + end; +end; + +procedure TWideStrings.SaveToStream(Stream: TStream); +var + SW: WideString; +begin + SW := GetTextStr; + Stream.WriteBuffer(PWideChar(SW)^, Length(SW) * SizeOf(WideChar)); +end; + +procedure TWideStrings.SetCapacity(NewCapacity: Integer); +begin + // do nothing - descendents may optionally implement this method +end; + +procedure TWideStrings.SetCommaText(const Value: WideString); +begin + Delimiter := ','; + QuoteChar := '"'; + SetDelimitedText(Value); +end; + +procedure TWideStrings.SetStringsAdapter(const Value: IWideStringsAdapter); +begin + if FAdapter <> nil then FAdapter.ReleaseStrings; + FAdapter := Value; + if FAdapter <> nil then FAdapter.ReferenceStrings(Self); +end; + +procedure TWideStrings.SetTextW(const Text: PWideChar); +begin + SetTextStr(Text); +end; + +procedure TWideStrings.SetTextStr(const Value: WideString); +var + P, Start: PWideChar; + S: WideString; +begin + BeginUpdate; + try + Clear; + P := Pointer(Value); + if P <> nil then + while P^ <> #0 do + begin + Start := P; + while not (P^ in [WideChar(#0), WideChar(#10), WideChar(#13)]) and (P^ <> WideLineSeparator) do + Inc(P); + SetString(S, Start, P - Start); + Add(S); + if P^ = #13 then Inc(P); + if P^ = #10 then Inc(P); + if P^ = WideLineSeparator then Inc(P); + end; + finally + EndUpdate; + end; +end; + +procedure TWideStrings.SetUpdateState(Updating: Boolean); +begin +end; + +procedure TWideStrings.SetValue(const Name, Value: WideString); +var + I: Integer; +begin + I := IndexOfName(Name); + if Value <> '' then + begin + if I < 0 then I := Add(''); + Put(I, Name + NameValueSeparator + Value); + end else + begin + if I >= 0 then Delete(I); + end; +end; + +procedure TWideStrings.WriteData(Writer: TWriter); +var + I: Integer; +begin + Writer.WriteListBegin; + for I := 0 to Count-1 do begin + Writer.WriteWideString(Get(I)); + end; + Writer.WriteListEnd; +end; + +procedure TWideStrings.SetDelimitedText(const Value: WideString); +var + P, P1: PWideChar; + S: WideString; +begin + BeginUpdate; + try + Clear; + P := PWideChar(Value); + while P^ in [WideChar(#1)..WideChar(' ')] do + Inc(P); + while P^ <> #0 do + begin + if P^ = QuoteChar then + S := WideExtractQuotedStr(P, QuoteChar) + else + begin + P1 := P; + while (P^ > ' ') and (P^ <> Delimiter) do + Inc(P); + SetString(S, P1, P - P1); + end; + Add(S); + while P^ in [WideChar(#1)..WideChar(' ')] do + Inc(P); + if P^ = Delimiter then + begin + P1 := P; + Inc(P1); + if P1^ = #0 then + Add(''); + repeat + Inc(P); + until not (P^ in [WideChar(#1)..WideChar(' ')]); + end; + end; + finally + EndUpdate; + end; +end; + +function TWideStrings.GetDelimiter: WideChar; +begin + if not (sdDelimiter in FDefined) then + Delimiter := ','; + Result := FDelimiter; +end; + +function TWideStrings.GetQuoteChar: WideChar; +begin + if not (sdQuoteChar in FDefined) then + QuoteChar := '"'; + Result := FQuoteChar; +end; + +procedure TWideStrings.SetDelimiter(const Value: WideChar); +begin + if (FDelimiter <> Value) or not (sdDelimiter in FDefined) then + begin + Include(FDefined, sdDelimiter); + FDelimiter := Value; + end +end; + +procedure TWideStrings.SetQuoteChar(const Value: WideChar); +begin + if (FQuoteChar <> Value) or not (sdQuoteChar in FDefined) then + begin + Include(FDefined, sdQuoteChar); + FQuoteChar := Value; + end +end; + +function TWideStrings.CompareStrings(const S1, S2: WideString): Integer; +begin + Result := WideCompareText(S1, S2); +end; + +function TWideStrings.GetNameValueSeparator: WideChar; +begin + {$IFDEF NAMEVALUESEPARATOR_RW} + if not (sdNameValueSeparator in FDefined) then + NameValueSeparator := '='; + Result := FNameValueSeparator; + {$ELSE} + Result := '='; + {$ENDIF} +end; + +{$IFDEF NAMEVALUESEPARATOR_RW} +procedure TWideStrings.SetNameValueSeparator(const Value: WideChar); +begin + if (FNameValueSeparator <> Value) or not (sdNameValueSeparator in FDefined) then + begin + Include(FDefined, sdNameValueSeparator); + FNameValueSeparator := Value; + end +end; +{$ENDIF} + +function TWideStrings.GetValueFromIndex(Index: Integer): WideString; +begin + if Index >= 0 then + Result := Copy(Get(Index), Length(Names[Index]) + 2, MaxInt) else + Result := ''; +end; + +procedure TWideStrings.SetValueFromIndex(Index: Integer; const Value: WideString); +begin + if Value <> '' then + begin + if Index < 0 then Index := Add(''); + Put(Index, Names[Index] + NameValueSeparator + Value); + end + else + if Index >= 0 then Delete(Index); +end; + +end. diff --git a/cmake/src/lib/TntUnicodeControls/TntWindows.pas b/cmake/src/lib/TntUnicodeControls/TntWindows.pas new file mode 100644 index 00000000..8fd7ec88 --- /dev/null +++ b/cmake/src/lib/TntUnicodeControls/TntWindows.pas @@ -0,0 +1,1501 @@ + +{*****************************************************************************} +{ } +{ Tnt Delphi Unicode Controls } +{ http://www.tntware.com/delphicontrols/unicode/ } +{ Version: 2.3.0 } +{ } +{ Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com) } +{ } +{*****************************************************************************} + +unit TntWindows; + +{$IFDEF FPC} + {$MODE Delphi} +{$ENDIF} + +{$INCLUDE TntCompilers.inc} + +interface + +uses + Windows, ShellApi, ShlObj; + +// ......... compatibility + +const + DT_NOFULLWIDTHCHARBREAK = $00080000; + +const + INVALID_FILE_ATTRIBUTES = DWORD(-1); + +// ................ ANSI TYPES ................ +{TNT-WARN LPSTR} +{TNT-WARN PLPSTR} +{TNT-WARN LPCSTR} +{TNT-WARN LPCTSTR} +{TNT-WARN LPTSTR} + +// ........ EnumResourceTypesW, EnumResourceNamesW and EnumResourceLanguagesW are supposed .... +// ........ to work on Win95/98/ME but have caused access violations in testing on Win95 ...... +// .. TNT--WARN EnumResourceTypes .. +// .. TNT--WARN EnumResourceTypesA .. +// .. TNT--WARN EnumResourceNames .. +// .. TNT--WARN EnumResourceNamesA .. +// .. TNT--WARN EnumResourceLanguages .. +// .. TNT--WARN EnumResourceLanguagesA .. + +//------------------------------------------------------------------------------------------ + +// ......... The Unicode form of these functions are supported on Windows 95/98/ME ......... +{TNT-WARN ExtTextOut} +{TNT-WARN ExtTextOutA} +{TNT-WARN Tnt_ExtTextOutW} + +{TNT-WARN FindResource} +{TNT-WARN FindResourceA} +{TNT-WARN Tnt_FindResourceW} + +{TNT-WARN FindResourceEx} +{TNT-WARN FindResourceExA} +{TNT-WARN Tnt_FindResourceExW} + +{TNT-WARN GetCharWidth} +{TNT-WARN GetCharWidthA} +{TNT-WARN Tnt_GetCharWidthW} + +{TNT-WARN GetCommandLine} +{TNT-WARN GetCommandLineA} +{TNT-WARN Tnt_GetCommandLineW} + +{TNT-WARN GetTextExtentPoint} +{TNT-WARN GetTextExtentPointA} +{TNT-WARN Tnt_GetTextExtentPointW} + +{TNT-WARN GetTextExtentPoint32} +{TNT-WARN GetTextExtentPoint32A} +{TNT-WARN Tnt_GetTextExtentPoint32W} + +{TNT-WARN lstrcat} +{TNT-WARN lstrcatA} +{TNT-WARN Tnt_lstrcatW} + +{TNT-WARN lstrcpy} +{TNT-WARN lstrcpyA} +{TNT-WARN Tnt_lstrcpyW} + +{TNT-WARN lstrlen} +{TNT-WARN lstrlenA} +{TNT-WARN Tnt_lstrlenW} + +{TNT-WARN MessageBox} +{TNT-WARN MessageBoxA} +{TNT-WARN Tnt_MessageBoxW} + +{TNT-WARN MessageBoxEx} +{TNT-WARN MessageBoxExA} +{TNT-WARN Tnt_MessageBoxExA} + +{TNT-WARN TextOut} +{TNT-WARN TextOutA} +{TNT-WARN Tnt_TextOutW} + +//------------------------------------------------------------------------------------------ + +{TNT-WARN LOCALE_USER_DEFAULT} // <-- use GetThreadLocale +{TNT-WARN LOCALE_SYSTEM_DEFAULT} // <-- use GetThreadLocale + +//------------------------------------------------------------------------------------------ +// compatiblity +//------------------------------------------------------------------------------------------ +{$IFNDEF COMPILER_9_UP} +type + {$IFDEF FPC} + TStartupInfoA = STARTUPINFO; + TStartupInfoW = STARTUPINFO; + {$ELSE} + TStartupInfoA = _STARTUPINFOA; + TStartupInfoW = record + cb: DWORD; + lpReserved: PWideChar; + lpDesktop: PWideChar; + lpTitle: PWideChar; + dwX: DWORD; + dwY: DWORD; + dwXSize: DWORD; + dwYSize: DWORD; + dwXCountChars: DWORD; + dwYCountChars: DWORD; + dwFillAttribute: DWORD; + dwFlags: DWORD; + wShowWindow: Word; + cbReserved2: Word; + lpReserved2: PByte; + hStdInput: THandle; + hStdOutput: THandle; + hStdError: THandle; + end; + {$ENDIF} + +function CreateProcessW{TNT-ALLOW CreateProcessW}(lpApplicationName: PWideChar; lpCommandLine: PWideChar; + lpProcessAttributes, lpThreadAttributes: PSecurityAttributes; + bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer; + lpCurrentDirectory: PWideChar; const lpStartupInfo: TStartupInfoW; + var lpProcessInformation: TProcessInformation): BOOL; stdcall; external kernel32 name 'CreateProcessW'; + +{$ENDIF} + +{$IFDEF FPC} +type + TCurrencyFmtA = CURRENCYFMT; + TCurrencyFmtW = CURRENCYFMT; + PCurrencyFmtA = ^TCurrencyFmtA; + PCurrencyFmtW = ^TCurrencyFmtW; +{$ENDIF} + +//------------------------------------------------------------------------------------------ + +{TNT-WARN SetWindowText} +{TNT-WARN SetWindowTextA} +{TNT-WARN SetWindowTextW} +function Tnt_SetWindowTextW(hWnd: HWND; lpString: PWideChar): BOOL; + +{TNT-WARN RemoveDirectory} +{TNT-WARN RemoveDirectoryA} +{TNT-WARN RemoveDirectoryW} +function Tnt_RemoveDirectoryW(lpPathName: PWideChar): BOOL; + +{TNT-WARN GetShortPathName} +{TNT-WARN GetShortPathNameA} +{TNT-WARN GetShortPathNameW} +function Tnt_GetShortPathNameW(lpszLongPath: PWideChar; lpszShortPath: PWideChar; + cchBuffer: DWORD): DWORD; + +{TNT-WARN GetFullPathName} +{TNT-WARN GetFullPathNameA} +{TNT-WARN GetFullPathNameW} +function Tnt_GetFullPathNameW(lpFileName: PWideChar; nBufferLength: DWORD; + lpBuffer: PWideChar; var lpFilePart: PWideChar): DWORD; + +{TNT-WARN CreateFile} +{TNT-WARN CreateFileA} +{TNT-WARN CreateFileW} +function Tnt_CreateFileW(lpFileName: PWideChar; dwDesiredAccess, dwShareMode: DWORD; + lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition, dwFlagsAndAttributes: DWORD; + hTemplateFile: THandle): THandle; + +{TNT-WARN FindFirstFile} +{TNT-WARN FindFirstFileA} +{TNT-WARN FindFirstFileW} +function Tnt_FindFirstFileW(lpFileName: PWideChar; var lpFindFileData: TWIN32FindDataW): THandle; + +{TNT-WARN FindNextFile} +{TNT-WARN FindNextFileA} +{TNT-WARN FindNextFileW} +function Tnt_FindNextFileW(hFindFile: THandle; var lpFindFileData: TWIN32FindDataW): BOOL; + +{TNT-WARN GetFileAttributes} +{TNT-WARN GetFileAttributesA} +{TNT-WARN GetFileAttributesW} +function Tnt_GetFileAttributesW(lpFileName: PWideChar): DWORD; + +{TNT-WARN SetFileAttributes} +{TNT-WARN SetFileAttributesA} +{TNT-WARN SetFileAttributesW} +function Tnt_SetFileAttributesW(lpFileName: PWideChar; dwFileAttributes: DWORD): BOOL; + +{TNT-WARN CreateDirectory} +{TNT-WARN CreateDirectoryA} +{TNT-WARN CreateDirectoryW} +function Tnt_CreateDirectoryW(lpPathName: PWideChar; + lpSecurityAttributes: PSecurityAttributes): BOOL; + +{TNT-WARN MoveFile} +{TNT-WARN MoveFileA} +{TNT-WARN MoveFileW} +function Tnt_MoveFileW(lpExistingFileName, lpNewFileName: PWideChar): BOOL; + +{TNT-WARN CopyFile} +{TNT-WARN CopyFileA} +{TNT-WARN CopyFileW} +function Tnt_CopyFileW(lpExistingFileName, lpNewFileName: PWideChar; bFailIfExists: BOOL): BOOL; + +{TNT-WARN DeleteFile} +{TNT-WARN DeleteFileA} +{TNT-WARN DeleteFileW} +function Tnt_DeleteFileW(lpFileName: PWideChar): BOOL; + +{TNT-WARN DrawText} +{TNT-WARN DrawTextA} +{TNT-WARN DrawTextW} +function Tnt_DrawTextW(hDC: HDC; lpString: PWideChar; nCount: Integer; + var lpRect: TRect; uFormat: UINT): Integer; + +{TNT-WARN GetDiskFreeSpace} +{TNT-WARN GetDiskFreeSpaceA} +{TNT-WARN GetDiskFreeSpaceW} +function Tnt_GetDiskFreeSpaceW(lpRootPathName: PWideChar; var lpSectorsPerCluster, + lpBytesPerSector, lpNumberOfFreeClusters, lpTotalNumberOfClusters: DWORD): BOOL; + +{TNT-WARN GetVolumeInformation} +{TNT-WARN GetVolumeInformationA} +{TNT-WARN GetVolumeInformationW} +function Tnt_GetVolumeInformationW(lpRootPathName: PWideChar; lpVolumeNameBuffer: PWideChar; + nVolumeNameSize: DWORD; lpVolumeSerialNumber: PDWORD; + var lpMaximumComponentLength, lpFileSystemFlags: DWORD; lpFileSystemNameBuffer: PWideChar; + nFileSystemNameSize: DWORD): BOOL; + +{TNT-WARN GetModuleFileName} +{TNT-WARN GetModuleFileNameA} +{TNT-WARN GetModuleFileNameW} +function Tnt_GetModuleFileNameW(hModule: HINST; lpFilename: PWideChar; nSize: DWORD): DWORD; + +{TNT-WARN GetTempPath} +{TNT-WARN GetTempPathA} +{TNT-WARN GetTempPathW} +function Tnt_GetTempPathW(nBufferLength: DWORD; lpBuffer: PWideChar): DWORD; + +{TNT-WARN GetTempFileName} +{TNT-WARN GetTempFileNameA} +{TNT-WARN GetTempFileNameW} +function Tnt_GetTempFileNameW(lpPathName, lpPrefixString: PWideChar; uUnique: UINT; + lpTempFileName: PWideChar): UINT; + +{TNT-WARN GetWindowsDirectory} +{TNT-WARN GetWindowsDirectoryA} +{TNT-WARN GetWindowsDirectoryW} +function Tnt_GetWindowsDirectoryW(lpBuffer: PWideChar; uSize: UINT): UINT; + +{TNT-WARN GetSystemDirectory} +{TNT-WARN GetSystemDirectoryA} +{TNT-WARN GetSystemDirectoryW} +function Tnt_GetSystemDirectoryW(lpBuffer: PWideChar; uSize: UINT): UINT; + +{TNT-WARN GetCurrentDirectory} +{TNT-WARN GetCurrentDirectoryA} +{TNT-WARN GetCurrentDirectoryW} +function Tnt_GetCurrentDirectoryW(nBufferLength: DWORD; lpBuffer: PWideChar): DWORD; + +{TNT-WARN SetCurrentDirectory} +{TNT-WARN SetCurrentDirectoryA} +{TNT-WARN SetCurrentDirectoryW} +function Tnt_SetCurrentDirectoryW(lpPathName: PWideChar): BOOL; + +{TNT-WARN GetComputerName} +{TNT-WARN GetComputerNameA} +{TNT-WARN GetComputerNameW} +function Tnt_GetComputerNameW(lpBuffer: PWideChar; var nSize: DWORD): BOOL; + +{TNT-WARN GetUserName} +{TNT-WARN GetUserNameA} +{TNT-WARN GetUserNameW} +function Tnt_GetUserNameW(lpBuffer: PWideChar; var nSize: DWORD): BOOL; + +{TNT-WARN ShellExecute} +{TNT-WARN ShellExecuteA} +{TNT-WARN ShellExecuteW} +function Tnt_ShellExecuteW(hWnd: HWND; Operation, FileName, Parameters, + Directory: PWideChar; ShowCmd: Integer): HINST; + +{TNT-WARN LoadLibrary} +{TNT-WARN LoadLibraryA} +{TNT-WARN LoadLibraryW} +function Tnt_LoadLibraryW(lpLibFileName: PWideChar): HMODULE; + +{TNT-WARN LoadLibraryEx} +{TNT-WARN LoadLibraryExA} +{TNT-WARN LoadLibraryExW} +function Tnt_LoadLibraryExW(lpLibFileName: PWideChar; hFile: THandle; dwFlags: DWORD): HMODULE; + +{TNT-WARN CreateProcess} +{TNT-WARN CreateProcessA} +{TNT-WARN CreateProcessW} +function Tnt_CreateProcessW(lpApplicationName: PWideChar; lpCommandLine: PWideChar; + lpProcessAttributes, lpThreadAttributes: PSecurityAttributes; + bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer; + lpCurrentDirectory: PWideChar; const lpStartupInfo: TStartupInfoW; + var lpProcessInformation: TProcessInformation): BOOL; + +{TNT-WARN GetCurrencyFormat} +{TNT-WARN GetCurrencyFormatA} +{TNT-WARN GetCurrencyFormatW} +function Tnt_GetCurrencyFormatW(Locale: LCID; dwFlags: DWORD; lpValue: PWideChar; + lpFormat: PCurrencyFmtW; lpCurrencyStr: PWideChar; cchCurrency: Integer): Integer; + +{TNT-WARN CompareString} +{TNT-WARN CompareStringA} +{TNT-WARN CompareStringW} +function Tnt_CompareStringW(Locale: LCID; dwCmpFlags: DWORD; lpString1: PWideChar; + cchCount1: Integer; lpString2: PWideChar; cchCount2: Integer): Integer; + +{TNT-WARN CharUpper} +{TNT-WARN CharUpperA} +{TNT-WARN CharUpperW} +function Tnt_CharUpperW(lpsz: PWideChar): PWideChar; + +{TNT-WARN CharUpperBuff} +{TNT-WARN CharUpperBuffA} +{TNT-WARN CharUpperBuffW} +function Tnt_CharUpperBuffW(lpsz: PWideChar; cchLength: DWORD): DWORD; + +{TNT-WARN CharLower} +{TNT-WARN CharLowerA} +{TNT-WARN CharLowerW} +function Tnt_CharLowerW(lpsz: PWideChar): PWideChar; + +{TNT-WARN CharLowerBuff} +{TNT-WARN CharLowerBuffA} +{TNT-WARN CharLowerBuffW} +function Tnt_CharLowerBuffW(lpsz: PWideChar; cchLength: DWORD): DWORD; + +{TNT-WARN GetStringTypeEx} +{TNT-WARN GetStringTypeExA} +{TNT-WARN GetStringTypeExW} +function Tnt_GetStringTypeExW(Locale: LCID; dwInfoType: DWORD; + lpSrcStr: PWideChar; cchSrc: Integer; var lpCharType): BOOL; + +{TNT-WARN LoadString} +{TNT-WARN LoadStringA} +{TNT-WARN LoadStringW} +function Tnt_LoadStringW(hInstance: HINST; uID: UINT; lpBuffer: PWideChar; nBufferMax: Integer): Integer; + +{$IFDEF FPC} +type + TMenuItemInfoW = TMENUITEMINFO; + tagMenuItemINFOW = tagMENUITEMINFO; +{$ENDIF} + +{TNT-WARN InsertMenuItem} +{TNT-WARN InsertMenuItemA} +{TNT-WARN InsertMenuItemW} +function Tnt_InsertMenuItemW(hMenu: HMENU; uItem: DWORD; fByPosition: BOOL; lpmii: tagMenuItemINFOW): BOOL; + +{TNT-WARN ExtractIconEx} +{TNT-WARN ExtractIconExA} +{TNT-WARN ExtractIconExW} +function Tnt_ExtractIconExW(lpszFile: PWideChar; nIconIndex: Integer; + var phiconLarge, phiconSmall: HICON; nIcons: UINT): UINT; + +{TNT-WARN ExtractAssociatedIcon} +{TNT-WARN ExtractAssociatedIconA} +{TNT-WARN ExtractAssociatedIconW} +function Tnt_ExtractAssociatedIconW(hInst: HINST; lpIconPath: PWideChar; + var lpiIcon: Word): HICON; + +{TNT-WARN GetFileVersionInfoSize} +{TNT-WARN GetFileVersionInfoSizeA} +{TNT-WARN GetFileVersionInfoSizeW} +function Tnt_GetFileVersionInfoSizeW(lptstrFilename: PWideChar; var lpdwHandle: DWORD): DWORD; + +{TNT-WARN GetFileVersionInfo} +{TNT-WARN GetFileVersionInfoA} +{TNT-WARN GetFileVersionInfoW} +function Tnt_GetFileVersionInfoW(lptstrFilename: PWideChar; dwHandle, dwLen: DWORD; + lpData: Pointer): BOOL; + +const + VQV_FIXEDFILEINFO = '\'; + VQV_VARFILEINFO_TRANSLATION = '\VarFileInfo\Translation'; + VQV_STRINGFILEINFO = '\StringFileInfo'; + + VER_COMMENTS = 'Comments'; + VER_INTERNALNAME = 'InternalName'; + VER_PRODUCTNAME = 'ProductName'; + VER_COMPANYNAME = 'CompanyName'; + VER_LEGALCOPYRIGHT = 'LegalCopyright'; + VER_PRODUCTVERSION = 'ProductVersion'; + VER_FILEDESCRIPTION = 'FileDescription'; + VER_LEGALTRADEMARKS = 'LegalTrademarks'; + VER_PRIVATEBUILD = 'PrivateBuild'; + VER_FILEVERSION = 'FileVersion'; + VER_ORIGINALFILENAME = 'OriginalFilename'; + VER_SPECIALBUILD = 'SpecialBuild'; + +{TNT-WARN VerQueryValue} +{TNT-WARN VerQueryValueA} +{TNT-WARN VerQueryValueW} +function Tnt_VerQueryValueW(pBlock: Pointer; lpSubBlock: PWideChar; + var lplpBuffer: Pointer; var puLen: UINT): BOOL; + +type +{$IFDEF FPC} + PSHNAMEMAPPINGA = ^SHNAMEMAPPINGA; + SHNAMEMAPPINGA = record + pszOldPath : LPSTR; + pszNewPath : LPSTR; + cchOldPath : longint; + cchNewPath : longint; + end; + + PSHNAMEMAPPINGW = ^SHNAMEMAPPINGW; + SHNAMEMAPPINGW = record + pszOldPath : LPWSTR; + pszNewPath : LPWSTR; + cchOldPath : longint; + cchNewPath : longint; + end; +{$ENDIF} + + TSHNameMappingHeaderA = record + cNumOfMappings: Cardinal; + lpNM: PSHNAMEMAPPINGA; + end; + PSHNameMappingHeaderA = ^TSHNameMappingHeaderA; + + TSHNameMappingHeaderW = record + cNumOfMappings: Cardinal; + lpNM: PSHNAMEMAPPINGW; + end; + PSHNameMappingHeaderW = ^TSHNameMappingHeaderW; + +{TNT-WARN SHFileOperation} +{TNT-WARN SHFileOperationA} +{TNT-WARN SHFileOperationW} // <-- no stub on early Windows 95 +function Tnt_SHFileOperationW(var lpFileOp: TSHFileOpStructW): Integer; + +{TNT-WARN SHFreeNameMappings} +procedure Tnt_SHFreeNameMappings(hNameMappings: THandle); + +{TNT-WARN SHBrowseForFolder} +{TNT-WARN SHBrowseForFolderA} +{TNT-WARN SHBrowseForFolderW} // <-- no stub on early Windows 95 +function Tnt_SHBrowseForFolderW(var lpbi: TBrowseInfoW): PItemIDList; + +{TNT-WARN SHGetPathFromIDList} +{TNT-WARN SHGetPathFromIDListA} +{TNT-WARN SHGetPathFromIDListW} // <-- no stub on early Windows 95 +function Tnt_SHGetPathFromIDListW(pidl: PItemIDList; pszPath: PWideChar): BOOL; + +{TNT-WARN SHGetFileInfo} +{TNT-WARN SHGetFileInfoA} +{TNT-WARN SHGetFileInfoW} // <-- no stub on early Windows 95 +function Tnt_SHGetFileInfoW(pszPath: PWideChar; dwFileAttributes: DWORD; + var psfi: TSHFileInfoW; cbFileInfo, uFlags: UINT): DWORD; + +// ......... introduced ......... +function Tnt_Is_IntResource(ResStr: LPCWSTR): Boolean; + +function LANGIDFROMLCID(lcid: LCID): WORD; +function MAKELANGID(usPrimaryLanguage, usSubLanguage: WORD): WORD; +function MAKELCID(wLanguageID: WORD; wSortID: WORD = SORT_DEFAULT): LCID; +function PRIMARYLANGID(lgid: WORD): WORD; +function SORTIDFROMLCID(lcid: LCID): WORD; +function SUBLANGID(lgid: WORD): WORD; + +implementation + +uses + SysUtils, Math, TntSysUtils, + {$IFDEF COMPILER_9_UP} WideStrUtils, {$ENDIF} TntWideStrUtils; + +function _PAnsiCharWithNil(const S: AnsiString): PAnsiChar; +begin + if S = '' then + Result := nil {Win9x needs nil for some parameters instead of empty strings} + else + Result := PAnsiChar(S); +end; + +function _PWideCharWithNil(const S: WideString): PWideChar; +begin + if S = '' then + Result := nil {Win9x needs nil for some parameters instead of empty strings} + else + Result := PWideChar(S); +end; + +function _WStr(lpString: PWideChar; cchCount: Integer): WideString; +begin + if cchCount = -1 then + Result := lpString + else + Result := Copy(WideString(lpString), 1, cchCount); +end; + +procedure _MakeWideWin32FindData(var WideFindData: TWIN32FindDataW; AnsiFindData: TWIN32FindDataA); +begin + CopyMemory(@WideFindData, @AnsiFindData, + PtrUInt(@WideFindData.cFileName) - PtrUInt(@WideFindData)); + WStrPCopy(WideFindData.cFileName, AnsiFindData.cFileName); + WStrPCopy(WideFindData.cAlternateFileName, AnsiFindData.cAlternateFileName); +end; + +function Tnt_SetWindowTextW(hWnd: HWND; lpString: PWideChar): BOOL; +begin + if Win32PlatformIsUnicode then + Result := SetWindowTextW{TNT-ALLOW SetWindowTextW}(hWnd, lpString) + else + Result := SetWindowTextA{TNT-ALLOW SetWindowTextA}(hWnd, PAnsiChar(AnsiString(lpString))); +end; + +//----------------------------- + +type + TPathLengthResultOption = (poAllowDirectoryMode, poZeroSmallBuff, poExactCopy, poExactCopySubPaths); + TPathLengthResultOptions = set of TPathLengthResultOption; + +procedure _ExactStrCopyW(pDest, pSource: PWideChar; Count: Integer); +var + i: integer; +begin + for i := 1 to Count do begin + pDest^ := pSource^; + Inc(PSource); + Inc(pDest); + end; +end; + +procedure _ExactCopySubPaths(pDest, pSource: PWideChar; Count: Integer); +var + i: integer; + OriginalSource: PWideChar; + PNextSlash: PWideChar; +begin + if Count >= 4 then begin + OriginalSource := pSource; + PNextSlash := WStrScan(pSource, '\'); + for i := 1 to Count - 1 do begin + // determine next path delimiter + if pSource > pNextSlash then begin + PNextSlash := WStrScan(pSource, '\'); + end; + // leave if no more sub paths + if (PNextSlash = nil) + or ((pNextSlash - OriginalSource) >= Count) then begin + exit; + end; + // copy char + pDest^ := pSource^; + Inc(PSource); + Inc(pDest); + end; + end; +end; + +function _HandlePathLengthResult(nBufferLength: DWORD; lpBuffer: PWideChar; const AnsiBuff: AnsiString; Options: TPathLengthResultOptions): Integer; +var + WideBuff: WideString; +begin + WideBuff := AnsiBuff; + if nBufferLength > Cardinal(Length(WideBuff)) then begin + // normal + Result := Length(WideBuff); + WStrLCopy(lpBuffer, PWideChar(WideBuff), nBufferLength); + end else if (poExactCopy in Options) then begin + // exact + Result := nBufferLength; + _ExactStrCopyW(lpBuffer, PWideChar(WideBuff), nBufferLength); + end else begin + // other + if (poAllowDirectoryMode in Options) + and (nBufferLength = Cardinal(Length(WideBuff))) then begin + Result := Length(WideBuff) + 1; + WStrLCopy(lpBuffer, PWideChar(WideBuff), nBufferLength - 1); + end else begin + Result := Length(WideBuff) + 1; + if (nBufferLength > 0) then begin + if (poZeroSmallBuff in Options) then + lpBuffer^ := #0 + else if (poExactCopySubPaths in Options) then + _ExactCopySubPaths(lpBuffer, PWideChar(WideBuff), nBufferLength); + end; + end; + end; +end; + +function _HandleStringLengthResult(nBufferLength: DWORD; lpBuffer: PWideChar; const AnsiBuff: AnsiString; Options: TPathLengthResultOptions): Integer; +var + WideBuff: WideString; +begin + WideBuff := AnsiBuff; + if nBufferLength >= Cardinal(Length(WideBuff)) then begin + // normal + Result := Length(WideBuff); + WStrLCopy(lpBuffer, PWideChar(WideBuff), nBufferLength); + end else if nBufferLength = 0 then + Result := Length(WideBuff) + else + Result := 0; +end; + +//------------------------------------------- + +function Tnt_RemoveDirectoryW(lpPathName: PWideChar): BOOL; +begin + if Win32PlatformIsUnicode then + Result := RemoveDirectoryW{TNT-ALLOW RemoveDirectoryW}(PWideChar(lpPathName)) + else + Result := RemoveDirectoryA{TNT-ALLOW RemoveDirectoryA}(PAnsiChar(AnsiString(lpPathName))); +end; + +function Tnt_GetShortPathNameW(lpszLongPath: PWideChar; lpszShortPath: PWideChar; + cchBuffer: DWORD): DWORD; +var + AnsiBuff: AnsiString; +begin + if Win32PlatformIsUnicode then + Result := GetShortPathNameW{TNT-ALLOW GetShortPathNameW}(lpszLongPath, lpszShortPath, cchBuffer) + else begin + SetLength(AnsiBuff, MAX_PATH * 2); + SetLength(AnsiBuff, GetShortPathNameA{TNT-ALLOW GetShortPathNameA}(PAnsiChar(AnsiString(lpszLongPath)), + PAnsiChar(AnsiBuff), Length(AnsiBuff))); + Result := _HandlePathLengthResult(cchBuffer, lpszShortPath, AnsiBuff, [poExactCopySubPaths]); + end; +end; + +function Tnt_GetFullPathNameW(lpFileName: PWideChar; nBufferLength: DWORD; + lpBuffer: PWideChar; var lpFilePart: PWideChar): DWORD; +var + AnsiBuff: AnsiString; + AnsiFilePart: PAnsiChar; + AnsiLeadingChars: Integer; + WideLeadingChars: Integer; +begin + if Win32PlatformIsUnicode then + Result := GetFullPathNameW{TNT-ALLOW GetFullPathNameW}(lpFileName, nBufferLength, lpBuffer, lpFilePart) + else begin + SetLength(AnsiBuff, MAX_PATH * 2); + SetLength(AnsiBuff, GetFullPathNameA{TNT-ALLOW GetFullPathNameA}(PAnsiChar(AnsiString(lpFileName)), + Length(AnsiBuff), PAnsiChar(AnsiBuff), AnsiFilePart)); + Result := _HandlePathLengthResult(nBufferLength, lpBuffer, AnsiBuff, [poZeroSmallBuff]); + // deal w/ lpFilePart + if (AnsiFilePart = nil) or (nBufferLength < Result) then + lpFilePart := nil + else begin + AnsiLeadingChars := AnsiFilePart - PAnsiChar(AnsiBuff); + WideLeadingChars := Length(WideString(Copy(AnsiBuff, 1, AnsiLeadingChars))); + lpFilePart := lpBuffer + WideLeadingChars; + end; + end; +end; + +function Tnt_CreateFileW(lpFileName: PWideChar; dwDesiredAccess, dwShareMode: DWORD; + lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition, dwFlagsAndAttributes: DWORD; + hTemplateFile: THandle): THandle; +begin + if Win32PlatformIsUnicode then + Result := CreateFileW{TNT-ALLOW CreateFileW}(lpFileName, dwDesiredAccess, dwShareMode, + lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile) + else + Result := CreateFileA{TNT-ALLOW CreateFileA}(PAnsiChar(AnsiString(lpFileName)), dwDesiredAccess, dwShareMode, + lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile) +end; + +function Tnt_FindFirstFileW(lpFileName: PWideChar; var lpFindFileData: TWIN32FindDataW): THandle; +var + Ansi_lpFindFileData: TWIN32FindDataA; +begin + if Win32PlatformIsUnicode then + Result := FindFirstFileW{TNT-ALLOW FindFirstFileW}(lpFileName, lpFindFileData) + else begin + Result := FindFirstFileA{TNT-ALLOW FindFirstFileA}(PAnsiChar(AnsiString(lpFileName)), + Ansi_lpFindFileData); + if Result <> INVALID_HANDLE_VALUE then + _MakeWideWin32FindData(lpFindFileData, Ansi_lpFindFileData); + end; +end; + +function Tnt_FindNextFileW(hFindFile: THandle; var lpFindFileData: TWIN32FindDataW): BOOL; +var + Ansi_lpFindFileData: TWIN32FindDataA; +begin + if Win32PlatformIsUnicode then + Result := FindNextFileW{TNT-ALLOW FindNextFileW}(hFindFile, lpFindFileData) + else begin + Result := FindNextFileA{TNT-ALLOW FindNextFileA}(hFindFile, Ansi_lpFindFileData); + if Result then + _MakeWideWin32FindData(lpFindFileData, Ansi_lpFindFileData); + end; +end; + +function Tnt_GetFileAttributesW(lpFileName: PWideChar): DWORD; +begin + if Win32PlatformIsUnicode then + Result := GetFileAttributesW{TNT-ALLOW GetFileAttributesW}(lpFileName) + else + Result := GetFileAttributesA{TNT-ALLOW GetFileAttributesA}(PAnsiChar(AnsiString(lpFileName))); +end; + +function Tnt_SetFileAttributesW(lpFileName: PWideChar; dwFileAttributes: DWORD): BOOL; +begin + if Win32PlatformIsUnicode then + Result := SetFileAttributesW{TNT-ALLOW SetFileAttributesW}(lpFileName, dwFileAttributes) + else + Result := SetFileAttributesA{TNT-ALLOW SetFileAttributesA}(PAnsiChar(AnsiString(lpFileName)), dwFileAttributes); +end; + +function Tnt_CreateDirectoryW(lpPathName: PWideChar; + lpSecurityAttributes: PSecurityAttributes): BOOL; +begin + if Win32PlatformIsUnicode then + Result := CreateDirectoryW{TNT-ALLOW CreateDirectoryW}(lpPathName, lpSecurityAttributes) + else + Result := CreateDirectoryA{TNT-ALLOW CreateDirectoryA}(PAnsiChar(AnsiString(lpPathName)), lpSecurityAttributes); +end; + +function Tnt_MoveFileW(lpExistingFileName, lpNewFileName: PWideChar): BOOL; +begin + if Win32PlatformIsUnicode then + Result := MoveFileW{TNT-ALLOW MoveFileW}(lpExistingFileName, lpNewFileName) + else + Result := MoveFileA{TNT-ALLOW MoveFileA}(PAnsiChar(AnsiString(lpExistingFileName)), PAnsiChar(AnsiString(lpNewFileName))); +end; + +function Tnt_CopyFileW(lpExistingFileName, lpNewFileName: PWideChar; bFailIfExists: BOOL): BOOL; +begin + if Win32PlatformIsUnicode then + Result := CopyFileW{TNT-ALLOW CopyFileW}(lpExistingFileName, lpNewFileName, bFailIfExists) + else + Result := CopyFileA{TNT-ALLOW CopyFileA}(PAnsiChar(AnsiString(lpExistingFileName)), + PAnsiChar(AnsiString(lpNewFileName)), bFailIfExists); +end; + +function Tnt_DeleteFileW(lpFileName: PWideChar): BOOL; +begin + if Win32PlatformIsUnicode then + Result := DeleteFileW{TNT-ALLOW DeleteFileW}(lpFileName) + else + Result := DeleteFileA{TNT-ALLOW DeleteFileA}(PAnsiChar(AnsiString(lpFileName))); +end; + +function Tnt_DrawTextW(hDC: HDC; lpString: PWideChar; nCount: Integer; + var lpRect: TRect; uFormat: UINT): Integer; +begin + if Win32PlatformIsUnicode then + Result := DrawTextW{TNT-ALLOW DrawTextW}(hDC, lpString, nCount, lpRect, uFormat) + else + Result := DrawTextA{TNT-ALLOW DrawTextA}(hDC, + PAnsiChar(AnsiString(_WStr(lpString, nCount))), -1, lpRect, uFormat); +end; + +function Tnt_GetDiskFreeSpaceW(lpRootPathName: PWideChar; var lpSectorsPerCluster, + lpBytesPerSector, lpNumberOfFreeClusters, lpTotalNumberOfClusters: DWORD): BOOL; +begin + if Win32PlatformIsUnicode then + Result := GetDiskFreeSpaceW{TNT-ALLOW GetDiskFreeSpaceW}(lpRootPathName, + lpSectorsPerCluster, lpBytesPerSector, lpNumberOfFreeClusters, lpTotalNumberOfClusters) + else + Result := GetDiskFreeSpaceA{TNT-ALLOW GetDiskFreeSpaceA}(PAnsiChar(AnsiString(lpRootPathName)), + lpSectorsPerCluster, lpBytesPerSector, lpNumberOfFreeClusters, lpTotalNumberOfClusters) +end; + +function Tnt_GetVolumeInformationW(lpRootPathName: PWideChar; lpVolumeNameBuffer: PWideChar; + nVolumeNameSize: DWORD; lpVolumeSerialNumber: PDWORD; + var lpMaximumComponentLength, lpFileSystemFlags: DWORD; lpFileSystemNameBuffer: PWideChar; + nFileSystemNameSize: DWORD): BOOL; +var + AnsiFileSystemNameBuffer: AnsiString; + AnsiVolumeNameBuffer: AnsiString; + AnsiBuffLen: DWORD; +begin + if Win32PlatformIsUnicode then + Result := GetVolumeInformationW{TNT-ALLOW GetVolumeInformationW}(lpRootPathName, lpVolumeNameBuffer, nVolumeNameSize, lpVolumeSerialNumber, lpMaximumComponentLength, lpFileSystemFlags, lpFileSystemNameBuffer, nFileSystemNameSize) + else begin + SetLength(AnsiVolumeNameBuffer, MAX_COMPUTERNAME_LENGTH + 1); + SetLength(AnsiFileSystemNameBuffer, MAX_COMPUTERNAME_LENGTH + 1); + AnsiBuffLen := Length(AnsiFileSystemNameBuffer); + Result := GetVolumeInformationA{TNT-ALLOW GetVolumeInformationA}(PAnsiChar(AnsiString(lpRootPathName)), PAnsiChar(AnsiVolumeNameBuffer), AnsiBuffLen, lpVolumeSerialNumber, lpMaximumComponentLength, lpFileSystemFlags, PAnsiChar(AnsiFileSystemNameBuffer), AnsiBuffLen); + if Result then begin + SetLength(AnsiFileSystemNameBuffer, AnsiBuffLen); + if (nFileSystemNameSize <= AnsiBuffLen) or (Length(AnsiFileSystemNameBuffer) = 0) then + Result := False + else begin + WStrPLCopy(lpFileSystemNameBuffer, AnsiFileSystemNameBuffer, nFileSystemNameSize); + WStrPLCopy(lpVolumeNameBuffer, AnsiVolumeNameBuffer, nVolumeNameSize); + end; + end; + end; +end; + +function Tnt_GetModuleFileNameW(hModule: HINST; lpFilename: PWideChar; nSize: DWORD): DWORD; +var + AnsiBuff: AnsiString; +begin + if Win32PlatformIsUnicode then + Result := GetModuleFileNameW{TNT-ALLOW GetModuleFileNameW}(hModule, lpFilename, nSize) + else begin + SetLength(AnsiBuff, MAX_PATH); + SetLength(AnsiBuff, GetModuleFileNameA{TNT-ALLOW GetModuleFileNameA}(hModule, PAnsiChar(AnsiBuff), Length(AnsiBuff))); + Result := _HandlePathLengthResult(nSize, lpFilename, AnsiBuff, [poExactCopy]); + end; +end; + +function Tnt_GetTempPathW(nBufferLength: DWORD; lpBuffer: PWideChar): DWORD; +var + AnsiBuff: AnsiString; +begin + if Win32PlatformIsUnicode then + Result := GetTempPathW{TNT-ALLOW GetTempPathW}(nBufferLength, lpBuffer) + else begin + SetLength(AnsiBuff, MAX_PATH); + SetLength(AnsiBuff, GetTempPathA{TNT-ALLOW GetTempPathA}(Length(AnsiBuff), PAnsiChar(AnsiBuff))); + Result := _HandlePathLengthResult(nBufferLength, lpBuffer, AnsiBuff, [poAllowDirectoryMode, poZeroSmallBuff]); + end; +end; + +function Tnt_GetTempFileNameW(lpPathName, lpPrefixString: PWideChar; uUnique: UINT; + lpTempFileName: PWideChar): UINT; +var + AnsiBuff: AnsiString; +begin + if Win32PlatformIsUnicode then + Result := GetTempFileNameW{TNT-ALLOW GetTempFileNameW}(lpPathName, lpPrefixString, uUnique, lpTempFileName) + else begin + SetLength(AnsiBuff, MAX_PATH); + Result := GetTempFileNameA{TNT-ALLOW GetTempFileNameA}(PAnsiChar(AnsiString(lpPathName)), PAnsiChar(lpPrefixString), uUnique, PAnsiChar(AnsiBuff)); + AnsiBuff := PAnsiChar(AnsiBuff); + _HandlePathLengthResult(MAX_PATH, lpTempFileName, AnsiBuff, [poZeroSmallBuff]); + end; +end; + +function Tnt_GetWindowsDirectoryW(lpBuffer: PWideChar; uSize: UINT): UINT; +var + AnsiBuff: AnsiString; +begin + if Win32PlatformIsUnicode then + Result := GetWindowsDirectoryW{TNT-ALLOW GetWindowsDirectoryW}(lpBuffer, uSize) + else begin + SetLength(AnsiBuff, MAX_PATH); + SetLength(AnsiBuff, GetWindowsDirectoryA{TNT-ALLOW GetWindowsDirectoryA}(PAnsiChar(AnsiBuff), Length(AnsiBuff))); + Result := _HandlePathLengthResult(uSize, lpBuffer, AnsiBuff, []); + end; +end; + +function Tnt_GetSystemDirectoryW(lpBuffer: PWideChar; uSize: UINT): UINT; +var + AnsiBuff: AnsiString; +begin + if Win32PlatformIsUnicode then + Result := GetSystemDirectoryW{TNT-ALLOW GetSystemDirectoryW}(lpBuffer, uSize) + else begin + SetLength(AnsiBuff, MAX_PATH); + SetLength(AnsiBuff, GetSystemDirectoryA{TNT-ALLOW GetSystemDirectoryA}(PAnsiChar(AnsiBuff), Length(AnsiBuff))); + Result := _HandlePathLengthResult(uSize, lpBuffer, AnsiBuff, []); + end; +end; + +function Tnt_GetCurrentDirectoryW(nBufferLength: DWORD; lpBuffer: PWideChar): DWORD; +var + AnsiBuff: AnsiString; +begin + if Win32PlatformIsUnicode then + Result := GetCurrentDirectoryW{TNT-ALLOW GetCurrentDirectoryW}(nBufferLength, lpBuffer) + else begin + SetLength(AnsiBuff, MAX_PATH); + SetLength(AnsiBuff, GetCurrentDirectoryA{TNT-ALLOW GetCurrentDirectoryA}(Length(AnsiBuff), PAnsiChar(AnsiBuff))); + Result := _HandlePathLengthResult(nBufferLength, lpBuffer, AnsiBuff, [poAllowDirectoryMode, poZeroSmallBuff]); + end; +end; + +function Tnt_SetCurrentDirectoryW(lpPathName: PWideChar): BOOL; +begin + if Win32PlatformIsUnicode then + Result := SetCurrentDirectoryW{TNT-ALLOW SetCurrentDirectoryW}(lpPathName) + else + Result := SetCurrentDirectoryA{TNT-ALLOW SetCurrentDirectoryA}(PAnsiChar(AnsiString(lpPathName))); +end; + +function Tnt_GetComputerNameW(lpBuffer: PWideChar; var nSize: DWORD): BOOL; +var + AnsiBuff: AnsiString; + AnsiBuffLen: DWORD; +begin + if Win32PlatformIsUnicode then + Result := GetComputerNameW{TNT-ALLOW GetComputerNameW}(lpBuffer, nSize) + else begin + SetLength(AnsiBuff, MAX_COMPUTERNAME_LENGTH + 1); + AnsiBuffLen := Length(AnsiBuff); + Result := GetComputerNameA{TNT-ALLOW GetComputerNameA}(PAnsiChar(AnsiBuff), AnsiBuffLen); + if Result then begin + SetLength(AnsiBuff, AnsiBuffLen); + if (nSize <= AnsiBuffLen) or (Length(AnsiBuff) = 0) then begin + nSize := AnsiBuffLen + 1; + Result := False; + end else begin + WStrPLCopy(lpBuffer, AnsiBuff, nSize); + nSize := WStrLen(lpBuffer); + end; + end; + end; +end; + +function Tnt_GetUserNameW(lpBuffer: PWideChar; var nSize: DWORD): BOOL; +var + AnsiBuff: AnsiString; + AnsiBuffLen: DWORD; +begin + if Win32PlatformIsUnicode then + Result := GetUserNameW{TNT-ALLOW GetUserNameW}(lpBuffer, nSize) + else begin + SetLength(AnsiBuff, 255); + AnsiBuffLen := Length(AnsiBuff); + Result := GetUserNameA{TNT-ALLOW GetUserNameA}(PAnsiChar(AnsiBuff), AnsiBuffLen); + if Result then begin + SetLength(AnsiBuff, AnsiBuffLen); + if (nSize <= AnsiBuffLen) or (Length(AnsiBuff) = 0) then begin + nSize := AnsiBuffLen + 1; + Result := False; + end else begin + WStrPLCopy(lpBuffer, AnsiBuff, nSize); + nSize := WStrLen(lpBuffer); + end; + end; + end; +end; + +function Tnt_ShellExecuteW(hWnd: HWND; Operation, FileName, Parameters, + Directory: PWideChar; ShowCmd: Integer): HINST; +begin + if Win32PlatformIsUnicode then + Result := ShellExecuteW{TNT-ALLOW ShellExecuteW}(hWnd, _PWideCharWithNil(WideString(Operation)), + FileName, Parameters, + Directory, ShowCmd) + else begin + Result := ShellExecuteA{TNT-ALLOW ShellExecuteA}(hWnd, _PAnsiCharWithNil(AnsiString(Operation)), + _PAnsiCharWithNil(AnsiString(FileName)), _PAnsiCharWithNil(AnsiString(Parameters)), + _PAnsiCharWithNil(AnsiString(Directory)), ShowCmd) + end; +end; + +function Tnt_LoadLibraryW(lpLibFileName: PWideChar): HMODULE; +begin + if Win32PlatformIsUnicode then + Result := LoadLibraryW{TNT-ALLOW LoadLibraryW}(lpLibFileName) + else + Result := LoadLibraryA{TNT-ALLOW LoadLibraryA}(PAnsiChar(AnsiString(lpLibFileName))); +end; + +function Tnt_LoadLibraryExW(lpLibFileName: PWideChar; hFile: THandle; dwFlags: DWORD): HMODULE; +begin + if Win32PlatformIsUnicode then + Result := LoadLibraryExW{TNT-ALLOW LoadLibraryExW}(lpLibFileName, hFile, dwFlags) + else + Result := LoadLibraryExA{TNT-ALLOW LoadLibraryExA}(PAnsiChar(AnsiString(lpLibFileName)), hFile, dwFlags); +end; + +function Tnt_CreateProcessW(lpApplicationName: PWideChar; lpCommandLine: PWideChar; + lpProcessAttributes, lpThreadAttributes: PSecurityAttributes; + bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer; + lpCurrentDirectory: PWideChar; const lpStartupInfo: TStartupInfoW; + var lpProcessInformation: TProcessInformation): BOOL; +var + AnsiStartupInfo: TStartupInfoA; +begin + if Win32PlatformIsUnicode then begin + Result := CreateProcessW{TNT-ALLOW CreateProcessW}(lpApplicationName, lpCommandLine, + lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, + lpCurrentDirectory, lpStartupInfo, lpProcessInformation) + end else begin + CopyMemory(@AnsiStartupInfo, @lpStartupInfo, SizeOf(TStartupInfo)); + AnsiStartupInfo.lpReserved := _PAnsiCharWithNil(AnsiString(lpStartupInfo.lpReserved)); + AnsiStartupInfo.lpDesktop := _PAnsiCharWithNil(AnsiString(lpStartupInfo.lpDesktop)); + AnsiStartupInfo.lpTitle := _PAnsiCharWithNil(AnsiString(lpStartupInfo.lpTitle)); + Result := CreateProcessA{TNT-ALLOW CreateProcessA}(_PAnsiCharWithNil(AnsiString(lpApplicationName)), + _PAnsiCharWithNil(AnsiString(lpCommandLine)), + lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, + _PAnsiCharWithNil(AnsiString(lpCurrentDirectory)), AnsiStartupInfo, lpProcessInformation); + end; +end; + +function Tnt_GetCurrencyFormatW(Locale: LCID; dwFlags: DWORD; lpValue: PWideChar; + lpFormat: PCurrencyFmtW; lpCurrencyStr: PWideChar; cchCurrency: Integer): Integer; +const + MAX_ANSI_BUFF_SIZE = 64; // can a currency string actually be larger? +var + AnsiFormat: TCurrencyFmtA; + PAnsiFormat: PCurrencyFmtA; + AnsiBuff: AnsiString; +begin + if Win32PlatformIsUnicode then + Result := GetCurrencyFormatW{TNT-ALLOW GetCurrencyFormatW}(Locale, dwFlags, lpValue, + {$IFNDEF FPC} lpFormat {$ELSE} PCurrencyFmt(lpFormat) {$ENDIF}, + lpCurrencyStr, cchCurrency) + else begin + if lpFormat = nil then + PAnsiFormat := nil + else begin + ZeroMemory(@AnsiFormat, SizeOf(AnsiFormat)); + AnsiFormat.NumDigits := lpFormat.NumDigits; + AnsiFormat.LeadingZero := lpFormat.LeadingZero; + AnsiFormat.Grouping := lpFormat.Grouping; + AnsiFormat.lpDecimalSep := PAnsiChar(AnsiString(lpFormat.lpDecimalSep)); + AnsiFormat.lpThousandSep := PAnsiChar(AnsiString(lpFormat.lpThousandSep)); + AnsiFormat.NegativeOrder := lpFormat.NegativeOrder; + AnsiFormat.PositiveOrder := lpFormat.PositiveOrder; + AnsiFormat.lpCurrencySymbol := PAnsiChar(AnsiString(lpFormat.lpCurrencySymbol)); + PAnsiFormat := @AnsiFormat; + end; + SetLength(AnsiBuff, MAX_ANSI_BUFF_SIZE); + SetLength(AnsiBuff, GetCurrencyFormatA{TNT-ALLOW GetCurrencyFormatA}(Locale, dwFlags, + PAnsiChar(AnsiString(lpValue)), PAnsiFormat, PAnsiChar(AnsiBuff), MAX_ANSI_BUFF_SIZE)); + Result := _HandleStringLengthResult(cchCurrency, lpCurrencyStr, AnsiBuff, []); + end; +end; + +function Tnt_CompareStringW(Locale: LCID; dwCmpFlags: DWORD; lpString1: PWideChar; + cchCount1: Integer; lpString2: PWideChar; cchCount2: Integer): Integer; +var + WideStr1, WideStr2: WideString; + AnsiStr1, AnsiStr2: AnsiString; +begin + if Win32PlatformIsUnicode then + Result := CompareStringW{TNT-ALLOW CompareStringW}(Locale, dwCmpFlags, lpString1, cchCount1, lpString2, cchCount2) + else begin + WideStr1 := _WStr(lpString1, cchCount1); + WideStr2 := _WStr(lpString2, cchCount2); + if (dwCmpFlags = 0) then begin + // binary comparison + if WideStr1 < WideStr2 then + Result := 1 + else if WideStr1 = WideStr2 then + Result := 2 + else + Result := 3; + end else begin + AnsiStr1 := WideStr1; + AnsiStr2 := WideStr2; + Result := CompareStringA{TNT-ALLOW CompareStringA}(Locale, dwCmpFlags, + PAnsiChar(AnsiStr1), -1, PAnsiChar(AnsiStr2), -1); + end; + end; +end; + +function Tnt_CharUpperW(lpsz: PWideChar): PWideChar; +var + AStr: AnsiString; + WStr: WideString; +begin + if Win32PlatformIsUnicode then + Result := CharUpperW{TNT-ALLOW CharUpperW}(lpsz) + else begin + if HiWord(Cardinal(lpsz)) = 0 then begin + // literal char mode + Result := lpsz; + if IsWideCharMappableToAnsi(WideChar(lpsz)) then begin + AStr := WideChar(lpsz); // single character may be more than one byte + CharUpperA{TNT-ALLOW CharUpperA}(PAnsiChar(AStr)); + WStr := AStr; // should always be single wide char + if Length(WStr) = 1 then + Result := PWideChar(WStr[1]); + end + end else begin + // null-terminated string mode + Result := lpsz; + while lpsz^ <> #0 do begin + lpsz^ := WideChar(Tnt_CharUpperW(PWideChar(lpsz^))); + Inc(lpsz); + end; + end; + end; +end; + +function Tnt_CharUpperBuffW(lpsz: PWideChar; cchLength: DWORD): DWORD; +var + i: integer; +begin + if Win32PlatformIsUnicode then + Result := CharUpperBuffW{TNT-ALLOW CharUpperBuffW}(lpsz, cchLength) + else begin + Result := cchLength; + for i := 1 to cchLength do begin + lpsz^ := WideChar(Tnt_CharUpperW(PWideChar(lpsz^))); + Inc(lpsz); + end; + end; +end; + +function Tnt_CharLowerW(lpsz: PWideChar): PWideChar; +var + AStr: AnsiString; + WStr: WideString; +begin + if Win32PlatformIsUnicode then + Result := CharLowerW{TNT-ALLOW CharLowerW}(lpsz) + else begin + if HiWord(Cardinal(lpsz)) = 0 then begin + // literal char mode + Result := lpsz; + if IsWideCharMappableToAnsi(WideChar(lpsz)) then begin + AStr := WideChar(lpsz); // single character may be more than one byte + CharLowerA{TNT-ALLOW CharLowerA}(PAnsiChar(AStr)); + WStr := AStr; // should always be single wide char + if Length(WStr) = 1 then + Result := PWideChar(WStr[1]); + end + end else begin + // null-terminated string mode + Result := lpsz; + while lpsz^ <> #0 do begin + lpsz^ := WideChar(Tnt_CharLowerW(PWideChar(lpsz^))); + Inc(lpsz); + end; + end; + end; +end; + +function Tnt_CharLowerBuffW(lpsz: PWideChar; cchLength: DWORD): DWORD; +var + i: integer; +begin + if Win32PlatformIsUnicode then + Result := CharLowerBuffW{TNT-ALLOW CharLowerBuffW}(lpsz, cchLength) + else begin + Result := cchLength; + for i := 1 to cchLength do begin + lpsz^ := WideChar(Tnt_CharLowerW(PWideChar(lpsz^))); + Inc(lpsz); + end; + end; +end; + +function Tnt_GetStringTypeExW(Locale: LCID; dwInfoType: DWORD; + lpSrcStr: PWideChar; cchSrc: Integer; var lpCharType): BOOL; +var + AStr: AnsiString; +begin + if Win32PlatformIsUnicode then + Result := GetStringTypeExW{TNT-ALLOW GetStringTypeExW}(Locale, dwInfoType, lpSrcStr, cchSrc, lpCharType) + else begin + AStr := _WStr(lpSrcStr, cchSrc); + Result := GetStringTypeExA{TNT-ALLOW GetStringTypeExA}(Locale, dwInfoType, + PAnsiChar(AStr), -1, lpCharType); + end; +end; + +function Win9x_LoadStringW(hInstance: HINST; uID: UINT; lpBuffer: PWideChar; nBufferMax: Integer): Integer; +// This function originated by the WINE Project. +// It was translated to Pascal by Francisco Leong. +// It was further modified by Troy Wolbrink. +var + hmem: HGLOBAL; + hrsrc: THandle; + p: PWideChar; + string_num, i: Integer; + block: Integer; +begin + Result := 0; + // Netscape v3 fix... + if (HIWORD(uID) = $FFFF) then begin + uID := UINT(-(Integer(uID))); + end; + // figure block, string_num + block := ((uID shr 4) and $FFFF) + 1; // bits 4 - 19, mask out bits 20 - 31, inc by 1 + string_num := uID and $000F; + // get handle & pointer to string block + hrsrc := FindResource{TNT-ALLOW FindResource}(hInstance, MAKEINTRESOURCE(block), RT_STRING); + if (hrsrc <> 0) then + begin + hmem := LoadResource(hInstance, hrsrc); + if (hmem <> 0) then + begin + p := LockResource(hmem); + // walk the block to the requested string + for i := 0 to string_num - 1 do begin + p := p + Integer(p^) + 1; + end; + Result := Integer(p^); { p points to the length of string } + Inc(p); { p now points to the actual string } + if (lpBuffer <> nil) and (nBufferMax > 0) then + begin + Result := min(nBufferMax - 1, Result); { max length to copy } + if (Result > 0) then begin + CopyMemory(lpBuffer, p, Result * sizeof(WideChar)); + end; + lpBuffer[Result] := WideChar(0); { null terminate } + end; + end; + end; +end; + +function Tnt_LoadStringW(hInstance: HINST; uID: UINT; lpBuffer: PWideChar; nBufferMax: Integer): Integer; +begin + if Win32PlatformIsUnicode then + Result := Windows.LoadStringW{TNT-ALLOW LoadStringW}(hInstance, uID, lpBuffer, nBufferMax) + else + Result := Win9x_LoadStringW(hInstance, uID, lpBuffer, nBufferMax); +end; + +function Tnt_InsertMenuItemW(hMenu: HMENU; uItem: DWORD; fByPosition: BOOL; lpmii: TMenuItemInfoW): BOOL; +begin + if Win32PlatformIsUnicode then + Result := InsertMenuItemW{TNT-ALLOW InsertMenuItemW}(hMenu, uItem, fByPosition, + {$IFDEF FPC}@{$ENDIF}lpmii) + else begin + TMenuItemInfoA(lpmii).dwTypeData := PAnsiChar(AnsiString(lpmii.dwTypeData)); + Result := InsertMenuItemA{TNT-ALLOW InsertMenuItemA}(hMenu, uItem, fByPosition, + {$IFDEF FPC}@{$ENDIF}TMenuItemInfoA(lpmii)); + end; +end; + +function Tnt_ExtractIconExW(lpszFile: PWideChar; nIconIndex: Integer; + var phiconLarge, phiconSmall: HICON; nIcons: UINT): UINT; +begin + if Win32PlatformIsUnicode then + Result := ExtractIconExW{TNT-ALLOW ExtractIconExW}(lpszFile, + nIconIndex, phiconLarge, phiconSmall, nIcons) + else + Result := ExtractIconExA{TNT-ALLOW ExtractIconExA}(PAnsiChar(AnsiString(lpszFile)), + nIconIndex, phiconLarge, phiconSmall, nIcons); +end; + +function Tnt_ExtractAssociatedIconW(hInst: HINST; lpIconPath: PWideChar; + var lpiIcon: Word): HICON; +begin + if Win32PlatformIsUnicode then + Result := ExtractAssociatedIconW{TNT-ALLOW ExtractAssociatedIconW}(hInst, + lpIconPath, {$IFDEF FPC}@{$ENDIF}lpiIcon) + else + Result := ExtractAssociatedIconA{TNT-ALLOW ExtractAssociatedIconA}(hInst, + PAnsiChar(AnsiString(lpIconPath)), {$IFDEF FPC}@{$ENDIF}lpiIcon) +end; + +function Tnt_GetFileVersionInfoSizeW(lptstrFilename: PWideChar; var lpdwHandle: DWORD): DWORD; +begin + if Win32PlatformIsUnicode then + Result := GetFileVersionInfoSizeW{TNT-ALLOW GetFileVersionInfoSizeW}(lptstrFilename, lpdwHandle) + else + Result := GetFileVersionInfoSizeA{TNT-ALLOW GetFileVersionInfoSizeA}(PAnsiChar(AnsiString(lptstrFilename)), lpdwHandle); +end; + +function Tnt_GetFileVersionInfoW(lptstrFilename: PWideChar; dwHandle, dwLen: DWORD; + lpData: Pointer): BOOL; +begin + if Win32PlatformIsUnicode then + Result := GetFileVersionInfoW{TNT-ALLOW GetFileVersionInfoW}(lptstrFilename, dwHandle, dwLen, lpData) + else + Result := GetFileVersionInfoA{TNT-ALLOW GetFileVersionInfoA}(PAnsiChar(AnsiString(lptstrFilename)), dwHandle, dwLen, lpData); +end; + +var + Last_VerQueryValue_String: WideString; + +function Tnt_VerQueryValueW(pBlock: Pointer; lpSubBlock: PWideChar; + var lplpBuffer: Pointer; var puLen: UINT): BOOL; +var + AnsiBuff: AnsiString; +begin + if Win32PlatformIsUnicode then + Result := VerQueryValueW{TNT-ALLOW VerQueryValueW}(pBlock, lpSubBlock, lplpBuffer, puLen) + else begin + Result := VerQueryValueA{TNT-ALLOW VerQueryValueA}(pBlock, PAnsiChar(AnsiString(lpSubBlock)), lplpBuffer, puLen); + if WideTextPos(VQV_STRINGFILEINFO, lpSubBlock) <> 1 then + else begin + { /StringFileInfo, convert ansi result to unicode } + SetString(AnsiBuff, PAnsiChar(lplpBuffer), puLen); + Last_VerQueryValue_String := AnsiBuff; + lplpBuffer := PWideChar(Last_VerQueryValue_String); + puLen := Length(Last_VerQueryValue_String); + end; + end; +end; + +//--------------------------------------------------------------------------------------- +// Wide functions from Shell32.dll should be loaded dynamically (no stub on early Win95) +//--------------------------------------------------------------------------------------- + +type + TSHFileOperationW = function(var lpFileOp: TSHFileOpStructW): Integer; stdcall; + TSHBrowseForFolderW = function(var lpbi: TBrowseInfoW): PItemIDList; stdcall; + TSHGetPathFromIDListW = function(pidl: PItemIDList; pszPath: PWideChar): BOOL; stdcall; + TSHGetFileInfoW = function(pszPath: PWideChar; dwFileAttributes: DWORD; + var psfi: TSHFileInfoW; cbFileInfo, uFlags: UINT): DWORD; stdcall; + +var + Safe_SHFileOperationW: TSHFileOperationW = nil; + Safe_SHBrowseForFolderW: TSHBrowseForFolderW = nil; + Safe_SHGetPathFromIDListW: TSHGetPathFromIDListW = nil; + Safe_SHGetFileInfoW: TSHGetFileInfoW = nil; + +var Shell32DLL: HModule = 0; + +procedure LoadWideShell32Procs; +begin + if Shell32DLL = 0 then begin + Shell32DLL := WinCheckH(Tnt_LoadLibraryW('shell32.dll')); + Safe_SHFileOperationW := WinCheckP(GetProcAddress(Shell32DLL, 'SHFileOperationW')); + Safe_SHBrowseForFolderW := WinCheckP(GetProcAddress(Shell32DLL, 'SHBrowseForFolderW')); + Safe_SHGetPathFromIDListW := WinCheckP(GetProcAddress(Shell32DLL, 'SHGetPathFromIDListW')); + Safe_SHGetFileInfoW := WinCheckP(GetProcAddress(Shell32DLL, 'SHGetFileInfoW')); + end; +end; + +function Tnt_SHFileOperationW(var lpFileOp: TSHFileOpStructW): Integer; +var + AnsiFileOp: TSHFileOpStructA; + MapCount: Integer; + PAnsiMap: PSHNameMappingA; + PWideMap: PSHNameMappingW; + OldPath: WideString; + NewPath: WideString; + i: integer; +begin + if Win32PlatformIsUnicode then begin + LoadWideShell32Procs; + Result := Safe_SHFileOperationW(lpFileOp); + end else begin + AnsiFileOp := TSHFileOpStructA(lpFileOp); + // convert PChar -> PWideChar + if lpFileOp.pFrom = nil then + AnsiFileOp.pFrom := nil + else + AnsiFileOp.pFrom := PAnsiChar(AnsiString(ExtractStringArrayStr(lpFileOp.pFrom))); + if lpFileOp.pTo = nil then + AnsiFileOp.pTo := nil + else + AnsiFileOp.pTo := PAnsiChar(AnsiString(ExtractStringArrayStr(lpFileOp.pTo))); + AnsiFileOp.lpszProgressTitle := PAnsiChar(AnsiString(lpFileOp.lpszProgressTitle)); + Result := SHFileOperationA{TNT-ALLOW SHFileOperationA}( + {$IFDEF FPC}@{$ENDIF}AnsiFileOp); + // return struct results + lpFileOp.fAnyOperationsAborted := AnsiFileOp.fAnyOperationsAborted; + lpFileOp.hNameMappings := nil; + if (AnsiFileOp.hNameMappings <> nil) + and ((FOF_WANTMAPPINGHANDLE and AnsiFileOp.fFlags) <> 0) then begin + // alloc mem + MapCount := PSHNameMappingHeaderA(AnsiFileOp.hNameMappings).cNumOfMappings; + lpFileOp.hNameMappings := + AllocMem(SizeOf({hNameMappings}Cardinal) + SizeOf(TSHNameMappingW) * MapCount); + PSHNameMappingHeaderW(lpFileOp.hNameMappings).cNumOfMappings := MapCount; + // init pointers + PAnsiMap := PSHNameMappingHeaderA(AnsiFileOp.hNameMappings).lpNM; + PWideMap := PSHNameMappingHeaderW(lpFileOp.hNameMappings).lpNM; + for i := 1 to MapCount do begin + // old path + OldPath := Copy(PAnsiMap.pszOldPath, 1, PAnsiMap.cchOldPath); + PWideMap.pszOldPath := WStrNew(PWideChar(OldPath)); + PWideMap.cchOldPath := WStrLen(PWideMap.pszOldPath); + // new path + NewPath := Copy(PAnsiMap.pszNewPath, 1, PAnsiMap.cchNewPath); + PWideMap.pszNewPath := WStrNew(PWideChar(NewPath)); + PWideMap.cchNewPath := WStrLen(PWideMap.pszNewPath); + // next record + Inc(PAnsiMap); + Inc(PWideMap); + end; + end; + end; +end; + +procedure Tnt_SHFreeNameMappings(hNameMappings: THandle); +var + i: integer; + MapCount: Integer; + PWideMap: PSHNameMappingW; +begin + if Win32PlatformIsUnicode then + SHFreeNameMappings{TNT-ALLOW SHFreeNameMappings}(hNameMappings) + else begin + // free strings + MapCount := PSHNameMappingHeaderW(hNameMappings).cNumOfMappings; + PWideMap := PSHNameMappingHeaderW(hNameMappings).lpNM; + for i := 1 to MapCount do begin + WStrDispose(PWideMap.pszOldPath); + WStrDispose(PWideMap.pszNewPath); + Inc(PWideMap); + end; + // free struct + FreeMem(Pointer(hNameMappings)); + end; +end; + +function Tnt_SHBrowseForFolderW(var lpbi: TBrowseInfoW): PItemIDList; +var + AnsiInfo: TBrowseInfoA; + AnsiBuffer: array[0..MAX_PATH] of AnsiChar; +begin + if Win32PlatformIsUnicode then begin + LoadWideShell32Procs; + Result := Safe_SHBrowseForFolderW(lpbi); + end else begin + AnsiInfo := TBrowseInfoA(lpbi); + AnsiInfo.lpszTitle := PAnsiChar(AnsiString(lpbi.lpszTitle)); + if lpbi.pszDisplayName <> nil then + AnsiInfo.pszDisplayName := AnsiBuffer; + Result := SHBrowseForFolderA{TNT-ALLOW SHBrowseForFolderA}( + {$IFDEF FPC}@{$ENDIF}AnsiInfo); + if lpbi.pszDisplayName <> nil then + WStrPCopy(lpbi.pszDisplayName, AnsiInfo.pszDisplayName); + lpbi.iImage := AnsiInfo.iImage; + end; +end; + +function Tnt_SHGetPathFromIDListW(pidl: PItemIDList; pszPath: PWideChar): BOOL; +var + AnsiPath: AnsiString; +begin + if Win32PlatformIsUnicode then begin + LoadWideShell32Procs; + Result := Safe_SHGetPathFromIDListW(pidl, pszPath); + end else begin + SetLength(AnsiPath, MAX_PATH); + Result := SHGetPathFromIDListA{TNT-ALLOW SHGetPathFromIDListA}(pidl, PAnsiChar(AnsiPath)); + if Result then + WStrPCopy(pszPath, PAnsiChar(AnsiPath)) + end; +end; + +function Tnt_SHGetFileInfoW(pszPath: PWideChar; dwFileAttributes: DWORD; + var psfi: TSHFileInfoW; cbFileInfo, uFlags: UINT): DWORD; +var + SHFileInfoA: TSHFileInfoA; +begin + if Win32PlatformIsUnicode then begin + LoadWideShell32Procs; + Result := Safe_SHGetFileInfoW(pszPath, dwFileAttributes, psfi, cbFileInfo, uFlags) + end else begin + Result := SHGetFileInfoA{TNT-ALLOW SHGetFileInfoA}(PAnsiChar(AnsiString(pszPath)), + dwFileAttributes, SHFileInfoA, SizeOf(TSHFileInfoA), uFlags); + // update pfsi... + ZeroMemory(@psfi, SizeOf(TSHFileInfoW)); + psfi.hIcon := SHFileInfoA.hIcon; + psfi.iIcon := SHFileInfoA.iIcon; + psfi.dwAttributes := SHFileInfoA.dwAttributes; + WStrPLCopy(psfi.szDisplayName, SHFileInfoA.szDisplayName, MAX_PATH); + WStrPLCopy(psfi.szTypeName, SHFileInfoA.szTypeName, 80); + end; +end; + + +function Tnt_Is_IntResource(ResStr: LPCWSTR): Boolean; +begin + Result := HiWord(Cardinal(ResStr)) = 0; +end; + +function LANGIDFROMLCID(lcid: LCID): WORD; +begin + Result := LoWord(lcid); +end; + +function MAKELANGID(usPrimaryLanguage, usSubLanguage: WORD): WORD; +begin + Result := (usSubLanguage shl 10) or usPrimaryLanguage; +end; + +function MAKELCID(wLanguageID: WORD; wSortID: WORD = SORT_DEFAULT): LCID; +begin + Result := MakeLong(wLanguageID, wSortID); +end; + +function PRIMARYLANGID(lgid: WORD): WORD; +begin + Result := lgid and $03FF; +end; + +function SORTIDFROMLCID(lcid: LCID): WORD; +begin + Result := HiWord(lcid); +end; + +function SUBLANGID(lgid: WORD): WORD; +begin + Result := lgid shr 10; +end; + +initialization + +finalization + if Shell32DLL <> 0 then + FreeLibrary(Shell32DLL); + +end. diff --git a/cmake/src/lib/bass/bass.chm b/cmake/src/lib/bass/bass.chm Binary files differindex 79ab64a2..8071fb0b 100644 --- a/cmake/src/lib/bass/bass.chm +++ b/cmake/src/lib/bass/bass.chm diff --git a/cmake/src/lib/bass/bass.txt b/cmake/src/lib/bass/bass.txt index cdaa7bf0..381519e1 100644 --- a/cmake/src/lib/bass/bass.txt +++ b/cmake/src/lib/bass/bass.txt @@ -1,5 +1,5 @@ BASS 2.4 -Copyright (c) 1999-2008 Un4seen Developments Ltd. All rights reserved. +Copyright (c) 1999-2009 Un4seen Developments Ltd. All rights reserved. Files that you should have found in the BASS package ==================================================== @@ -136,8 +136,8 @@ VB\ Visual Basic API and examples... MODLIVESPEC.BAS MULTI\ Multiple device example PRJMULTI.VBP - PRJMULTI.FRM - PRJDEVICE.FRM + FRMMULTI.FRM + FRMDEVICE.FRM NETRADIO\ Internet streaming example PRJNETRADIO.VBP FRMNETRADIO.FRM @@ -199,6 +199,8 @@ DELPHI\ Delphi API and examples... LIVEFX.DPR UNIT1.PAS UNIT1.DFM + LIVESPEC\ "Live" version of spectrum analyser example + LIVESPEC.DPR MULTI\ Multiple device example MULTI.DPR UNIT1.PAS @@ -229,6 +231,10 @@ DELPHI\ Delphi API and examples... SPEAKERS.DPR UNIT1.PAS UNIT1.DFM + SPECTRUM\ Spectrum analyser example + SPECTRUM.DPR + UNIT1.PAS + COMMON.INC STREAMTEST\ User stream example STREAMTEST.DPR STMAIN.PAS @@ -281,9 +287,12 @@ CUSTLOOP\ Custom looping example MAKEFILE DSPTEST\ DSP example DSPTEST.C - DSPTEST.RC MAKEFILE DSPTEST.NIB +FXTEST\ DX8 effect example + FXTEST.C + MAKEFILE + FXTEST.NIB LIVESPEC\ "Live" version of spectrum analyser example LIVESPEC.C MAKEFILE @@ -567,6 +576,73 @@ There are of course bug fixes and other little improvements made along the way too! To make upgrading simpler, all functions affected by a change to the BASS interface are listed. +2.4.5 - 18/12/2009 +------------------ +* Support for little-endian AIFF files + BASS_StreamCreateFile/User/Url + BASS_SampleLoad +* Support for 64-bit floating-point WAVE/AIFF files + BASS_StreamCreateFile/User/Url + BASS_SampleLoad +* Input volume retrieval failure results in a reading of -1 instead of 1 + BASS_RecordGetInput + RECTEST example updated +* Input volume support on OSX + BASS_RecordSetInput + BASS_RecordGetInput + RECTEST example updated +* Fix for deferred input settings on Vista + BASS_RecordSetInput +* Windows MP3 codec given preference over other installed MP3 codecs (MP3-FREE version) + BASS_StreamCreateFile/User/Url + BASS_SampleLoad + +2.4.4 - 13/10/2009 +------------------ +* RIFF/BWF "radio traffic" tag retrieval + BASS_TAG_RIFF_CART (BASS_ChannelGetTags type) + TAG_CART structure +* Support for ID3v2 tags in RIFF/WAVE/AIFF files ("ID3 " chunk) + BASS_TAG_ID3V2 (BASS_ChannelGetTags type) +* Pushed fractional samples are refused rather than discarded + BASS_StreamPutData +* DX8 effect emulation on OSX + BASS_FX_DX8_CHORUS/DISTORTION/ECHO/FLANGER/PARAMEQ/REVERB (BASS_ChannelSetFX types) + FXTEST example added +* UTF-16 support on OSX + BASS_UNICODE (BASS_StreamCreateFile/SampleLoad/MusicLoad/PluginLoad flag) + +2.4.3 - 8/5/2009 +---------------- +* MOD order list retrieval + BASS_TAG_MUSIC_ORDERS (BASS_ChannelGetTags type) +* Support for ID3v2 tags in RIFF/WAVE files ("id3 " chunk) + BASS_TAG_ID3V2 (BASS_ChannelGetTags type) +* Improved position reporting precision on Vista + BASS_ChannelGetPosition +* Length retrieval when streaming in blocks (BASS_STREAM_BLOCK) + BASS_ChannelGetLength +* Support for CoreAudio codecs on OSX + BASS_StreamCreateFile/User + BASS_SampleLoad + BASS_TAG_CA_CODEC (BASS_ChannelGetTags type) + TAG_CA_CODEC structure +* 3D algorithm option support on OSX + BASS_CONFIG_3DALGORITHM (BASS_SetConfig option) + +2.4.2 - 18/9/2008 +----------------- +* RF64 support + BASS_StreamCreateFile/User +* RIFF/BWF "Broadcast Audio Extension" tag retrieval + BASS_TAG_RIFF_BEXT (BASS_ChannelGetTags type) + TAG_BEXT structure +* ID3v1 tag structure + TAG_ID3 structure +* Multiple simultaneous recordings per device on Vista & OSX (as on XP) + BASS_RecordStart +* DX8 effect parameter defaults updated/corrected in documentation + 2.4 - 2/4/2008 -------------- * "Push" streaming @@ -588,7 +664,7 @@ change to the BASS interface are listed. BASS_FILEPOS_BUFFER (BASS_StreamGetFilePosition mode) * Sinc interpolated MOD music mixing BASS_MUSIC_SINCINTER (BASS_MusicLoad flag) -* MO3 v2.4 support +* MO3 2.4 support BASS_MusicLoad * MOD orders positioning incorporated into channel functions BASS_ChannelGetLength @@ -637,7 +713,7 @@ change to the BASS interface are listed. BASS_ChannelSetFlags *removed* SPEAKERS example updated * 256 sample FFT - BASS_DATA_FFT256 (BASS_ChannelGetDat flag) + BASS_DATA_FFT256 (BASS_ChannelGetData flag) * Channel locking to prevent access by other threads BASS_ChannelLock * Manual channel buffer updating @@ -730,7 +806,7 @@ change to the BASS interface are listed. BASS_ChannelStop * Sample channels created paused to prevent overriding before playback BASS_SampleGetChannel -* Separate "MP3-FREE" version using Windows/OSX MP3 decoder +* Separate "MP3-FREE" version using the OS's MP3 decoder BASS_CONFIG_MP3_CODEC *removed* 2.3.0.1 - 12/6/2006 @@ -1458,7 +1534,7 @@ change to the BASS interface are listed. 0.8 - 24/1/2000 --------------- -* Improved MP3 performance on P2/K6 and above CPUs - fast! +* Improved MP3 performance on P2/K6 and above CPUs * User DSP functions on streams and MOD musics BASS_ChannelSetDSP BASS_ChannelRemoveDSP @@ -1645,7 +1721,7 @@ API/Sample contributors Visual Basic: Adam Hoult, Hendrik Knaepen, Arthur Aminov, Peter Hebels Delphi: Titus Miloi, Rogier Timmermans, Alessandro Cappellozza, - Jesse Naranjo, Chris Troesken + Jesse Naranjo, Chris Troesken, Evgeny Melnikov MASM: Octavian Chis diff --git a/cmake/src/lib/bass/delphi/bass.pas b/cmake/src/lib/bass/delphi/bass.pas index 85d10355..e87b05f5 100644 --- a/cmake/src/lib/bass/delphi/bass.pas +++ b/cmake/src/lib/bass/delphi/bass.pas @@ -1,12 +1,14 @@ { BASS 2.4 Delphi unit - Copyright (c) 1999-2008 Un4seen Developments Ltd. + Copyright (c) 1999-2009 Un4seen Developments Ltd. See the BASS.CHM file for more detailed documentation How to install -------------- Copy BASS.PAS to the \LIB subdirectory of your Delphi path or your project dir + + NOTE: Delphi 2009 users should use the BASS_UNICODE flag where possible } unit Bass; @@ -24,12 +26,6 @@ interface {$DEFINE DLL_CDECL} {$ENDIF} -// IMPORTANT: define BASS_242 when switching to 2.4.2(.1) as -// BASS_RECORDINFO.driver was removed. -// Otherwise BASS_RECORDINFO.freq will point to a wrong location. -{$UNDEF BASS_242} - - {$IFDEF MSWINDOWS} uses Windows; @@ -40,7 +36,7 @@ const BASSVERSIONTEXT = '2.4'; // Use these to test for error from functions that return a DWORD or QWORD - DW_ERROR = Cardinal(-1); // -1 (DWORD) + DW_ERROR = LongWord(-1); // -1 (DWORD) QW_ERROR = Int64(-1); // -1 (QWORD) // Error codes returned by BASS_ErrorGetCode() @@ -100,6 +96,9 @@ const BASS_CONFIG_MUSIC_VIRTUAL = 22; BASS_CONFIG_VERIFY = 23; BASS_CONFIG_UPDATETHREADS = 24; + {$IFDEF LINUX} + BASS_CONFIG_DEV_BUFFER = 27; + {$ENDIF} // BASS_SetConfigPtr options BASS_CONFIG_NET_AGENT = 16; @@ -113,6 +112,9 @@ const BASS_DEVICE_CPSPEAKERS = 1024; // detect speakers via Windows control panel BASS_DEVICE_SPEAKERS = 2048; // force enabling of speaker assignment BASS_DEVICE_NOSPEAKER = 4096; // ignore speaker arrangement + {$IFDEF LINUX} + BASS_DEVICE_DMIX = 8192; // use "dmix" (shared) output + {$ENDIF} // DirectSound interfaces (for use with BASS_GetDSoundObject) BASS_OBJECT_DS = 1; // IDirectSound @@ -229,6 +231,7 @@ const BASS_CTYPE_STREAM_MP2 = $10004; BASS_CTYPE_STREAM_MP3 = $10005; BASS_CTYPE_STREAM_AIFF = $10006; + BASS_CTYPE_STREAM_CA = $10007; BASS_CTYPE_STREAM_WAV = $40000; // WAVE flag, LOWORD=codec BASS_CTYPE_STREAM_WAV_PCM = $50001; BASS_CTYPE_STREAM_WAV_FLOAT = $50003; @@ -250,7 +253,6 @@ const BASS_3DALG_FULL = 2; BASS_3DALG_LIGHT = 3; -{$IFDEF MSWINDOWS} // EAX environments, use with BASS_SetEAXParameters EAX_ENVIRONMENT_GENERIC = 0; EAX_ENVIRONMENT_PADDEDCELL = 1; @@ -280,7 +282,6 @@ const EAX_ENVIRONMENT_PSYCHOTIC = 25; // total number of environments EAX_ENVIRONMENT_COUNT = 26; -{$ENDIF} BASS_STREAMPROC_END = $80000000; // end of user stream flag @@ -359,17 +360,21 @@ const BASS_TAG_META = 5; // ICY metadata : ANSI string BASS_TAG_VENDOR = 9; // OGG encoder : UTF-8 string BASS_TAG_LYRICS3 = 10; // Lyric3v2 tag : ASCII string + BASS_TAG_CA_CODEC = 11; // CoreAudio codec info : TAG_CA_CODEC structure BASS_TAG_RIFF_INFO = $100; // RIFF "INFO" tags : series of null-terminated ANSI strings - BASS_TAG_RIFF_BEXT = $101; // RIFF/BWF Broadcast Audio Extension tags : TAG_BEXT structure + BASS_TAG_RIFF_BEXT = $101; // RIFF/BWF "bext" tags : TAG_BEXT structure + BASS_TAG_RIFF_CART = $102; // RIFF/BWF "cart" tags : TAG_CART structure BASS_TAG_MUSIC_NAME = $10000; // MOD music name : ANSI string BASS_TAG_MUSIC_MESSAGE = $10001; // MOD message : ANSI string + BASS_TAG_MUSIC_ORDERS = $10002; // MOD order list : BYTE array of pattern numbers BASS_TAG_MUSIC_INST = $10100; // + instrument #, MOD instrument name : ANSI string BASS_TAG_MUSIC_SAMPLE = $10300; // + sample #, MOD sample name : ANSI string // BASS_ChannelGetLength/GetPosition/SetPosition modes BASS_POS_BYTE = 0; // byte position BASS_POS_MUSIC_ORDER = 1; // order.row position, MAKELONG(order,row) - + BASS_POS_DECODE = $10000000; // flag: get the decoding (not playing) position + // BASS_RecordSetInput flags BASS_INPUT_OFF = $10000; BASS_INPUT_ON = $20000; @@ -404,10 +409,10 @@ const BASS_DX8_PHASE_180 = 4; type - DWORD = cardinal; + DWORD = LongWord; BOOL = LongBool; FLOAT = Single; - QWORD = int64; // 64-bit (replace "int64" with "comp" if using Delphi 3) + QWORD = Int64; HMUSIC = DWORD; // MOD music handle HSAMPLE = DWORD; // sample handle @@ -449,9 +454,6 @@ type formats: DWORD; // supported standard formats (WAVE_FORMAT_xxx flags) inputs: DWORD; // number of inputs singlein: BOOL; // only 1 input can be set at a time - {$IFNDEF BASS_242} - driver: PChar; // driver - {$ENDIF} freq: DWORD; // current input rate (OSX only) end; @@ -485,7 +487,7 @@ type origres: DWORD; // original resolution plugin: HPLUGIN; // plugin sample: HSAMPLE; // sample - filename: PAnsiChar; // filename + filename: PChar; // filename end; BASS_PLUGINFORM = record @@ -534,7 +536,7 @@ type genre: Byte; end; - // BWF Broadcast Audio Extension tag structure + // BWF "bext" tag structure TAG_BEXT = record Description: Array[0..255] of AnsiChar; // description Originator: Array[0..31] of AnsiChar; // name of the originator @@ -548,6 +550,42 @@ type CodingHistory: Array of AnsiChar; // history end; + // BWF "cart" tag structures + TAG_CART_TIMER = record + dwUsage: DWORD; // FOURCC timer usage ID + dwValue: DWORD; // timer value in samples from head + end; + + TAG_CART = record + Version: array [0..3] of AnsiChar; // version of the data structure + Title: array [0..63] of AnsiChar; // title of cart audio sequence + Artist: array [0..63] of AnsiChar; // artist or creator name + CutID: array [0..63] of AnsiChar; // cut number identification + ClientID: array [0..63] of AnsiChar; // client identification + Category: array [0..63] of AnsiChar; // category ID, PSA, NEWS, etc + Classification: array [0..63] of AnsiChar; // classification or auxiliary key + OutCue: array [0..63] of AnsiChar; // out cue text + StartDate: array [0..9] of AnsiChar; // yyyy-mm-dd + StartTime: array [0..7] of AnsiChar; // hh:mm:ss + EndDate: array [0..9] of AnsiChar; // yyyy-mm-dd + EndTime: array [0..7] of AnsiChar; // hh:mm:ss + ProducerAppID: array [0..63] of AnsiChar; // name of vendor or application + ProducerAppVersion: array [0..63] of AnsiChar; // version of producer application + UserDef: array [0..63] of AnsiChar; // user defined text + dwLevelReference: DWORD; // sample value for 0 dB reference + PostTimer: array [0..7] of TAG_CART_TIMER; // 8 time markers after head + Reserved: array [0..275] of AnsiChar; + URL: array [0..1023] of AnsiChar; // uniform resource locator + TagText: array [0..0] of AnsiChar; // free form text for scripts or tags + end; + + // CoreAudio codec info structure + TAG_CA_CODEC = record + ftype: DWORD; // file format + atype: DWORD; // audio format + name: {const} PAnsiChar; // description + end; + BASS_DX8_CHORUS = record fWetDryMix: FLOAT; fDepth: FLOAT; @@ -599,14 +637,14 @@ type end; BASS_DX8_I3DL2REVERB = record - lRoom: Longint; // [-10000, 0] default: -1000 mB - lRoomHF: Longint; // [-10000, 0] default: 0 mB + lRoom: LongInt; // [-10000, 0] default: -1000 mB + lRoomHF: LongInt; // [-10000, 0] default: 0 mB flRoomRolloffFactor: FLOAT; // [0.0, 10.0] default: 0.0 flDecayTime: FLOAT; // [0.1, 20.0] default: 1.49s flDecayHFRatio: FLOAT; // [0.1, 2.0] default: 0.83 - lReflections: Longint; // [-10000, 1000] default: -2602 mB + lReflections: LongInt; // [-10000, 1000] default: -2602 mB flReflectionsDelay: FLOAT; // [0.0, 0.3] default: 0.007 s - lReverb: Longint; // [-10000, 2000] default: 200 mB + lReverb: LongInt; // [-10000, 2000] default: 200 mB flReverbDelay: FLOAT; // [0.0, 0.1] default: 0.011 s flDiffusion: FLOAT; // [0.0, 100.0] default: 100.0 % flDensity: FLOAT; // [0.0, 100.0] default: 100.0 % @@ -695,6 +733,9 @@ const {$IFDEF MSWINDOWS} bassdll = 'bass.dll'; {$ENDIF} +{$IFDEF LINUX} + bassdll = 'bass'; +{$ENDIF} {$IFDEF DARWIN} bassdll = 'libbass.dylib'; {$linklib libbass} @@ -705,12 +746,12 @@ function BASS_GetConfig(option: DWORD): DWORD; {$IFDEF DLL_STDCALL}stdcall;{$END function BASS_SetConfigPtr(option: DWORD; value: Pointer): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; function BASS_GetConfigPtr(option: DWORD): Pointer; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; function BASS_GetVersion: DWORD; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; -function BASS_ErrorGetCode: Integer; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; +function BASS_ErrorGetCode: LongInt; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; function BASS_GetDeviceInfo(device: DWORD; var info: BASS_DEVICEINFO): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; {$IFDEF MSWINDOWS} -function BASS_Init(device: Integer; freq, flags: DWORD; win: HWND; clsid: PGUID): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; +function BASS_Init(device: LongInt; freq, flags: DWORD; win: HWND; clsid: PGUID): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; {$ELSE} -function BASS_Init(device: Integer; freq, flags: DWORD; win: Pointer; clsid: Pointer): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; +function BASS_Init(device: LongInt; freq, flags: DWORD; win: Pointer; clsid: Pointer): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; {$ENDIF} function BASS_SetDevice(device: DWORD): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; function BASS_GetDevice: DWORD; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; @@ -727,7 +768,7 @@ function BASS_Pause: BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL function BASS_SetVolume(volume: FLOAT): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; function BASS_GetVolume: FLOAT; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; -function BASS_PluginLoad(filename: PAnsiChar; flags: DWORD): HPLUGIN; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; +function BASS_PluginLoad(filename: PChar; flags: DWORD): HPLUGIN; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; function BASS_PluginFree(handle: HPLUGIN): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; function BASS_PluginGetInfo(handle: HPLUGIN): PBASS_PLUGININFO; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; @@ -737,7 +778,7 @@ function BASS_Set3DPosition(var pos, vel, front, top: BASS_3DVECTOR): BOOL; {$IF function BASS_Get3DPosition(var pos, vel, front, top: BASS_3DVECTOR): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; procedure BASS_Apply3D; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; {$IFDEF MSWINDOWS} -function BASS_SetEAXParameters(env: Integer; vol, decay, damp: FLOAT): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; +function BASS_SetEAXParameters(env: LongInt; vol, decay, damp: FLOAT): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; function BASS_GetEAXParameters(var env: DWORD; var vol, decay, damp: FLOAT): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; {$ENDIF} @@ -765,14 +806,14 @@ function BASS_StreamPutData(handle: HSTREAM; buffer: Pointer; length: DWORD): DW function BASS_StreamPutFileData(handle: HSTREAM; buffer: Pointer; length: DWORD): DWORD; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; function BASS_RecordGetDeviceInfo(device: DWORD; var info: BASS_DEVICEINFO): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; -function BASS_RecordInit(device: Integer):BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; +function BASS_RecordInit(device: LongInt):BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; function BASS_RecordSetDevice(device: DWORD): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; function BASS_RecordGetDevice: DWORD; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; function BASS_RecordFree: BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; function BASS_RecordGetInfo(var info: BASS_RECORDINFO): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; -function BASS_RecordGetInputName(input: Integer): PAnsiChar; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; -function BASS_RecordSetInput(input: Integer; flags: DWORD; volume: FLOAT): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; -function BASS_RecordGetInput(input: Integer; var volume: FLOAT): DWORD; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; +function BASS_RecordGetInputName(input: LongInt): PAnsiChar; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; +function BASS_RecordSetInput(input: LongInt; flags: DWORD; volume: FLOAT): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; +function BASS_RecordGetInput(input: LongInt; var volume: FLOAT): DWORD; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; function BASS_RecordStart(freq, chans, flags: DWORD; proc: RECORDPROC; user: Pointer): HRECORD; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; function BASS_ChannelBytes2Seconds(handle: DWORD; pos: QWORD): Double; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF}external bassdll; @@ -792,7 +833,7 @@ function BASS_ChannelSetAttribute(handle, attrib: DWORD; value: FLOAT): BOOL; {$ function BASS_ChannelGetAttribute(handle, attrib: DWORD; var value: FLOAT): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; function BASS_ChannelSlideAttribute(handle, attrib: DWORD; value: FLOAT; time: DWORD): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; function BASS_ChannelIsSliding(handle, attrib: DWORD): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF}external bassdll; -function BASS_ChannelSet3DAttributes(handle: DWORD; mode: Integer; min, max: FLOAT; iangle, oangle, outvol: Integer): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; +function BASS_ChannelSet3DAttributes(handle: DWORD; mode: LongInt; min, max: FLOAT; iangle, oangle, outvol: LongInt): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; function BASS_ChannelGet3DAttributes(handle: DWORD; var mode: DWORD; var min, max: FLOAT; var iangle, oangle, outvol: DWORD): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; function BASS_ChannelSet3DPosition(handle: DWORD; var pos, orient, vel: BASS_3DVECTOR): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; function BASS_ChannelGet3DPosition(handle: DWORD; var pos, orient, vel: BASS_3DVECTOR): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; @@ -803,11 +844,11 @@ function BASS_ChannelGetLevel(handle: DWORD): DWORD; {$IFDEF DLL_STDCALL}stdcall function BASS_ChannelGetData(handle: DWORD; buffer: Pointer; length: DWORD): DWORD; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; function BASS_ChannelSetSync(handle: DWORD; type_: DWORD; param: QWORD; proc: SYNCPROC; user: Pointer): HSYNC; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; function BASS_ChannelRemoveSync(handle: DWORD; sync: HSYNC): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; -function BASS_ChannelSetDSP(handle: DWORD; proc: DSPPROC; user: Pointer; priority: Integer): HDSP; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; +function BASS_ChannelSetDSP(handle: DWORD; proc: DSPPROC; user: Pointer; priority: LongInt): HDSP; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; function BASS_ChannelRemoveDSP(handle: DWORD; dsp: HDSP): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; function BASS_ChannelSetLink(handle, chan: DWORD): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; function BASS_ChannelRemoveLink(handle, chan: DWORD): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; -function BASS_ChannelSetFX(handle, type_: DWORD; priority: Integer): HFX; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; +function BASS_ChannelSetFX(handle, type_: DWORD; priority: LongInt): HFX; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; function BASS_ChannelRemoveFX(handle: DWORD; fx: HFX): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; function BASS_FXSetParameters(handle: HFX; par: Pointer): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$IFDEF DLL_CDECL}cdecl;{$ENDIF} external bassdll; @@ -817,7 +858,7 @@ function BASS_FXReset(handle: HFX): BOOL; {$IFDEF DLL_STDCALL}stdcall;{$ENDIF}{$ function BASS_SPEAKER_N(n: DWORD): DWORD; {$IFDEF MSWINDOWS} -function BASS_SetEAXPreset(env: Integer): BOOL; +function BASS_SetEAXPreset(env: LongInt): BOOL; { This function is defined in the implementation part of this unit. It is not part of BASS.DLL but an extra function which makes it easier @@ -834,7 +875,7 @@ begin end; {$IFDEF MSWINDOWS} -function BASS_SetEAXPreset(env: Integer): BOOL; +function BASS_SetEAXPreset(env: LongInt): BOOL; begin case (env) of EAX_ENVIRONMENT_GENERIC: diff --git a/cmake/src/lib/ctypes/ctypes.pas b/cmake/src/lib/ctypes/ctypes.pas index 6cdf77fc..694552dc 100644 --- a/cmake/src/lib/ctypes/ctypes.pas +++ b/cmake/src/lib/ctypes/ctypes.pas @@ -1,72 +1,72 @@ -{
- This file is part of the Free Pascal run time library.
- Copyright (c) 2004 by Marco van de Voort, member of the
- Free Pascal development team
-
- Implements C types for in header conversions
-
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-
- **********************************************************************}
-
-unit ctypes;
-
-interface
-
-type
- qword = int64; // Keep h2pas "uses ctypes" headers working with delphi.
-
- { the following type definitions are compiler dependant }
- { and system dependant }
-
- cint8 = shortint; pcint8 = ^cint8;
- cuint8 = byte; pcuint8 = ^cuint8;
- cchar = cint8; pcchar = ^cchar;
- cschar = cint8; pcschar = ^cschar;
- cuchar = cuint8; pcuchar = ^cuchar;
-
- cint16 = smallint; pcint16 = ^cint16;
- cuint16 = word; pcuint16 = ^cuint16;
- cshort = cint16; pcshort = ^cshort;
- csshort = cint16; pcsshort = ^csshort;
- cushort = cuint16; pcushort = ^cushort;
-
- cint32 = longint; pcint32 = ^cint32;
- cuint32 = longword; pcuint32 = ^cuint32;
- cint = cint32; pcint = ^cint; { minimum range is : 32-bit }
- csint = cint32; pcsint = ^csint; { minimum range is : 32-bit }
- cuint = cuint32; pcuint = ^cuint; { minimum range is : 32-bit }
- csigned = cint; pcsigned = ^csigned;
- cunsigned = cuint; pcunsigned = ^cunsigned;
-
- cint64 = int64; pcint64 = ^cint64;
- cuint64 = qword; pcuint64 = ^cuint64;
- clonglong = cint64; pclonglong = ^clonglong;
- cslonglong = cint64; pcslonglong = ^cslonglong;
- culonglong = cuint64; pculonglong = ^culonglong;
-
- cbool = longbool; pcbool = ^cbool;
-
-{$if defined(cpu64) and not(defined(win64) and defined(cpux86_64))}
- clong = int64; pclong = ^clong;
- cslong = int64; pcslong = ^cslong;
- culong = qword; pculong = ^culong;
-{$else}
- clong = longint; pclong = ^clong;
- cslong = longint; pcslong = ^cslong;
- culong = cardinal; pculong = ^culong;
-{$ifend}
-
- cfloat = single; pcfloat = ^cfloat;
- cdouble = double; pcdouble = ^cdouble;
- clongdouble = extended; pclongdouble = ^clongdouble;
-
-implementation
-
-end.
+{ + This file is part of the Free Pascal run time library. + Copyright (c) 2004 by Marco van de Voort, member of the + Free Pascal development team + + Implements C types for in header conversions + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + + **********************************************************************} + +unit ctypes; + +interface + +type + qword = int64; // Keep h2pas "uses ctypes" headers working with delphi. + + { the following type definitions are compiler dependant } + { and system dependant } + + cint8 = shortint; pcint8 = ^cint8; + cuint8 = byte; pcuint8 = ^cuint8; + cchar = cint8; pcchar = ^cchar; + cschar = cint8; pcschar = ^cschar; + cuchar = cuint8; pcuchar = ^cuchar; + + cint16 = smallint; pcint16 = ^cint16; + cuint16 = word; pcuint16 = ^cuint16; + cshort = cint16; pcshort = ^cshort; + csshort = cint16; pcsshort = ^csshort; + cushort = cuint16; pcushort = ^cushort; + + cint32 = longint; pcint32 = ^cint32; + cuint32 = longword; pcuint32 = ^cuint32; + cint = cint32; pcint = ^cint; { minimum range is : 32-bit } + csint = cint32; pcsint = ^csint; { minimum range is : 32-bit } + cuint = cuint32; pcuint = ^cuint; { minimum range is : 32-bit } + csigned = cint; pcsigned = ^csigned; + cunsigned = cuint; pcunsigned = ^cunsigned; + + cint64 = int64; pcint64 = ^cint64; + cuint64 = qword; pcuint64 = ^cuint64; + clonglong = cint64; pclonglong = ^clonglong; + cslonglong = cint64; pcslonglong = ^cslonglong; + culonglong = cuint64; pculonglong = ^culonglong; + + cbool = longbool; pcbool = ^cbool; + +{$if defined(cpu64) and not(defined(win64) and defined(cpux86_64))} + clong = int64; pclong = ^clong; + cslong = int64; pcslong = ^cslong; + culong = qword; pculong = ^culong; +{$else} + clong = longint; pclong = ^clong; + cslong = longint; pcslong = ^cslong; + culong = cardinal; pculong = ^culong; +{$ifend} + + cfloat = single; pcfloat = ^cfloat; + cdouble = double; pcdouble = ^cdouble; + clongdouble = extended; pclongdouble = ^clongdouble; + +implementation + +end. diff --git a/cmake/src/lib/ffmpeg/avcodec.pas b/cmake/src/lib/ffmpeg/avcodec.pas index ceb1b7f0..7e55e13a 100644 --- a/cmake/src/lib/ffmpeg/avcodec.pas +++ b/cmake/src/lib/ffmpeg/avcodec.pas @@ -27,13 +27,9 @@ (* * Conversion of libavcodec/avcodec.h * Min. version: 51.16.0, revision 6577, Sat Oct 7 15:30:46 2006 UTC - * Max. version: 52.11.0, revision 16912, Sun Feb 1 02:00:19 2009 UTC + * Max. version: 52.67.2, revision 23191, Wed May 19 19:30 2010 CET + * *) -{ - * update to - * Max. version: 52.31.2, Sar Jun 13 22:05:00 2009 UTC - * MiSchi -} unit avcodec; @@ -63,9 +59,34 @@ uses UConfig; const + (* + * IMPORTANT: The official FFmpeg C headers change very quickly. Often some + * of the data structures are changed so that they become incompatible with + * older header files. The Pascal headers have to be adjusted to those changes, + * otherwise the application might crash randomly or strange bugs (not + * necessarily related to video or audio due to buffer overflows etc.) might + * occur. + * + * In the past users reported problems with USDX that took hours to fix and + * the problem was an unsupported version of FFmpeg. So we decided to disable + * support for future versions of FFmpeg until the headers are revised by us + * for that version as they otherwise most probably will break USDX. + * + * If the headers do not yet support your FFmpeg version you may want to + * adjust the max. version numbers manually but please note: it may work but + * in many cases it does not. The USDX team does NOT PROVIDE ANY SUPPORT + * for the game if the MAX. VERSION WAS CHANGED. + * + * The only safe way to support new versions of FFmpeg is to add the changes + * of the FFmpeg git repository C headers to the Pascal headers. + * You can accelerate this process by posting a patch with the git changes + * translated to Pascal to our bug tracker (please join our IRC chat before + * you start working on it). Simply adjusting the max. versions is NOT a valid + * fix. + *) (* Max. supported version by this header *) LIBAVCODEC_MAX_VERSION_MAJOR = 52; - LIBAVCODEC_MAX_VERSION_MINOR = 31; + LIBAVCODEC_MAX_VERSION_MINOR = 67; LIBAVCODEC_MAX_VERSION_RELEASE = 2; LIBAVCODEC_MAX_VERSION = (LIBAVCODEC_MAX_VERSION_MAJOR * VERSION_MAJOR) + (LIBAVCODEC_MAX_VERSION_MINOR * VERSION_MINOR) + @@ -173,7 +194,9 @@ type CODEC_ID_QDRAW, CODEC_ID_VIXL, CODEC_ID_QPEG, +{$IF LIBAVCODEC_VERSION_MAJOR < 53} CODEC_ID_XVID, +{$IFEND} CODEC_ID_PNG, CODEC_ID_PPM, CODEC_ID_PBM, @@ -260,6 +283,33 @@ type {$IF LIBAVCODEC_VERSION >= 52031002} // >= 52.31.2 CODEC_ID_MAD, {$IFEND} +{$IF LIBAVCODEC_VERSION >= 52037000} // >= 52.37.0 + CODEC_ID_FRWU, +{$IFEND} +{$IF LIBAVCODEC_VERSION >= 52041000} // >= 52.41.0 + CODEC_ID_FLASHSV2, +{$IFEND} +{$IF LIBAVCODEC_VERSION >= 52043000} // >= 52.43.0 + CODEC_ID_CDGRAPHICS, + CODEC_ID_R210, +{$IFEND} + CODEC_ID_ANM, +{$IF LIBAVCODEC_VERSION >= 52049000} // >= 52.49.0 + CODEC_ID_BINKVIDEO, +{$IFEND} +{$IF LIBAVCODEC_VERSION >= 52052000} // >= 52.52.0 + CODEC_ID_IFF_ILBM, + CODEC_ID_IFF_BYTERUN1, +{$IFEND} +{$IF LIBAVCODEC_VERSION >= 52058000} // >= 52.58.0 + CODEC_ID_KGV1, +{$IFEND} +{$IF LIBAVCODEC_VERSION >= 52062000} // >= 52.62.0 + CODEC_ID_YOP, +{$IFEND} +{$IF LIBAVCODEC_VERSION >= 52067002} // >= 52.67.2 + CODEC_ID_VP8, +{$IFEND} //* various PCM "codecs" */ CODEC_ID_PCM_S16LE= $10000, @@ -286,6 +336,9 @@ type CODEC_ID_PCM_F32LE, CODEC_ID_PCM_F64BE, CODEC_ID_PCM_F64LE, +{$IF LIBAVCODEC_VERSION >= 52034000} // >= 52.34.0 + CODEC_ID_PCM_BLURAY, +{$IFEND} //* various ADPCM codecs */ CODEC_ID_ADPCM_IMA_QT= $11000, @@ -390,6 +443,13 @@ type {$IF LIBAVCODEC_VERSION >= 52026000} // >= 52.26.0 CODEC_ID_MP4ALS, {$IFEND} +{$IF LIBAVCODEC_VERSION >= 52035000} // >= 52.35.0 + CODEC_ID_ATRAC1, +{$IFEND} +{$IF LIBAVCODEC_VERSION >= 52049000} // >= 52.49.0 + CODEC_ID_BINKAUDIO_RDFT, + CODEC_ID_BINKAUDIO_DCT, +{$IFEND} //* subtitle codecs */ CODEC_ID_DVD_SUBTITLE= $17000, @@ -398,6 +458,12 @@ type CODEC_ID_XSUB, CODEC_ID_SSA, CODEC_ID_MOV_TEXT, +{$IF LIBAVCODEC_VERSION >= 52033000} // >= 52.33.0 + CODEC_ID_HDMV_PGS_SUBTITLE, +{$IFEND} +{$IF LIBAVCODEC_VERSION >= 52037001} // >= 52.37.1 + CODEC_ID_DVB_TELETEXT, +{$IFEND} (* other specific kind of codecs (generally used for attachments) *) CODEC_ID_TTF= $18000, @@ -416,6 +482,7 @@ const CODEC_ID_MPEG4AAC = CODEC_ID_AAC; {$IFEND} +{$IF LIBAVCODEC_VERSION_MAJOR < 53} // < 53.0.0 type TCodecType = ( CODEC_TYPE_UNKNOWN = -1, @@ -426,6 +493,25 @@ type CODEC_TYPE_ATTACHMENT, CODEC_TYPE_NB ); +{$IFEND} + +{ + TAVMediaType moved to avutil in LIBAVUTIL_VERSION 50.14.0 + but moving it in the pascal headers was not really necessary + but caused problems. So, I (KMS) left it here. +} +{$IF LIBAVCODEC_VERSION >= 52064000} // >= 52.64.0 +type + TAVMediaType = ( + AVMEDIA_TYPE_UNKNOWN = -1, + AVMEDIA_TYPE_VIDEO, + AVMEDIA_TYPE_AUDIO, + AVMEDIA_TYPE_DATA, + AVMEDIA_TYPE_SUBTITLE, + AVMEDIA_TYPE_ATTACHMENT, + AVMEDIA_TYPE_NB + ); +{$IFEND} {** * all in native endian @@ -465,6 +551,13 @@ const CH_TOP_BACK_RIGHT = $00020000; CH_STEREO_LEFT = $20000000; ///< Stereo downmix. CH_STEREO_RIGHT = $40000000; ///< See CH_STEREO_LEFT. +{** Channel mask value used for AVCodecContext.request_channel_layout + * to indicate that the user requests the channel order of the decoder output + * to be the native codec channel order. + *} +{$IF LIBAVCODEC_VERSION >= 52038001} // >= 52.38.1 + CH_LAYOUT_NATIVE = $8000000000000000; +{$IFEND} {* Audio channel convenience macros *} CH_LAYOUT_MONO = (CH_FRONT_CENTER); @@ -483,6 +576,9 @@ const CH_BACK_RIGHT); CH_LAYOUT_5POINT1_BACK = (CH_LAYOUT_5POINT0_BACK or CH_LOW_FREQUENCY); {$IFEND} +{$IF LIBAVCODEC_VERSION >= 52034000} // >= 52.34.0 + CH_LAYOUT_7POINT0 = (CH_LAYOUT_5POINT0 or CH_BACK_LEFT or CH_BACK_RIGHT); +{$IFEND} CH_LAYOUT_7POINT1 = (CH_LAYOUT_5POINT1 or CH_BACK_LEFT or CH_BACK_RIGHT); {$IF LIBAVCODEC_VERSION < 52025000} // < 52.25.0 CH_LAYOUT_7POINT1_WIDE = (CH_LAYOUT_SURROUND or CH_LOW_FREQUENCY or @@ -494,11 +590,30 @@ const CH_FRONT_RIGHT_OF_CENTER); CH_LAYOUT_STEREO_DOWNMIX = (CH_STEREO_LEFT or CH_STEREO_RIGHT); - -const - {* in bytes *} +{* in bytes *} AVCODEC_MAX_AUDIO_FRAME_SIZE = 192000; // 1 second of 48khz 32bit audio +{$IF LIBAVCODEC_VERSION <= 52056000} // <= 52.56.0 +{** + * Required number of additionally allocated bytes at the end of the input bitstream for decoding. + * This is mainly needed because some optimized bitstream readers read + * 32 or 64 bit at once and could read over the end.<br> + * Note: If the first 23 bits of the additional bytes are not 0, then damaged + * MPEG bitstreams could cause overread and segfault. + *} + FF_INPUT_BUFFER_PADDING_SIZE = 8; +{$ELSEIF LIBAVCODEC_VERSION < 52058000} // < 52.58.0 +{** + * Required number of additionally allocated bytes at the end of the input bitstream for decoding. + * The first 8 bytes are needed because some optimized bitstream readers read + * 32 or 64 bit at once and could read over the end. The remainder is to give + * decoders a reasonable amount of distance to work with before checking for + * buffer overreads.<br> + * Note: If the first 23 bits of the additional bytes are not 0, then damaged + * MPEG bitstreams could cause overread and segfault. + *} + FF_INPUT_BUFFER_PADDING_SIZE = 64; +{$ELSE} // >= 52.58.0} {** * Required number of additionally allocated bytes at the end of the input bitstream for decoding. * This is mainly needed because some optimized bitstream readers read @@ -507,6 +622,7 @@ const * MPEG bitstreams could cause overread and segfault. *} FF_INPUT_BUFFER_PADDING_SIZE = 8; +{$IFEND} {** * minimum encoding buffer size. @@ -676,6 +792,16 @@ const CODEC_FLAG2_CHUNKS = $00008000; ///< Input bitstream might be truncated at a packet boundaries instead of only at frame boundaries. CODEC_FLAG2_NON_LINEAR_QUANT = $00010000; ///< Use MPEG-2 nonlinear quantizer. CODEC_FLAG2_BIT_RESERVOIR = $00020000; ///< Use a bit reservoir when encoding if possible + {$IF LIBAVCODEC_VERSION >= 52043000} // >= 52.43.0 + CODEC_FLAG2_MBTREE = $00040000; ///< Use macroblock tree ratecontrol (x264 only) + {$IFEND} + {$IF LIBAVCODEC_VERSION >= 52061000} // >= 52.61.0 + CODEC_FLAG2_PSY = $00080000; ///< Use psycho visual optimizations. + CODEC_FLAG2_SSIM = $00100000; ///< Compute SSIM during encoding, error[] values are undefined. + {$IFEND} + {$IF LIBAVCODEC_VERSION >= 52067000} // >= 52.67.0 + CODEC_FLAG2_INTRA_REFRESH = $00200000; ///< Use periodic insertion of intra blocks instead of keyframes. + {$IFEND} (* Unsupported options : * Syntax Arithmetic coding (SAC) @@ -684,11 +810,11 @@ const (* /Fx *) (* codec capabilities *) -const CODEC_CAP_DRAW_HORIZ_BAND = $0001; ///< decoder can use draw_horiz_band callback (** - * Codec uses get_buffer() for allocating buffers. - * direct rendering method 1 + * Codec uses get_buffer() for allocating buffers and supports custom allocators. + * If not set, it might not use get_buffer() at all or use operations that + * assume the buffer was allocated by avcodec_default_get_buffer. *) CODEC_CAP_DR1 = $0002; (* if 'parse_only' field is true, then avcodec_parse_frame() can be used *) @@ -712,6 +838,21 @@ const *) CODEC_CAP_HWACCEL_VDPAU = $0080; + {$IF LIBAVCODEC_VERSION >= 52035000} // >= 52.35.0 + (** + * Codec can output multiple frames per AVPacket + * Normally demuxers return one frame at a time, demuxers which do not do + * are connected to a parser to split what they return into proper frames. + * This flag is reserved to the very rare category of codecs which have a + * bitstream that cannot be split into frames without timeconsuming + * operations like full decoding. Demuxers carring such bitstreams thus + * may return multiple frames in a packet. This has many disadvantages like + * prohibiting stream copy in many cases thus it should only be considered + * as a last resort. + *) + CODEC_CAP_SUBFRAMES = $0100; + {$IFEND} + //the following defines may change, don't expect compatibility if you use them MB_TYPE_INTRA4x4 = $001; MB_TYPE_INTRA16x16 = $002; //FIXME h264 specific @@ -765,6 +906,9 @@ const FF_QSCALE_TYPE_MPEG1 = 0; FF_QSCALE_TYPE_MPEG2 = 1; FF_QSCALE_TYPE_H264 = 2; + {$IF LIBAVCODEC_VERSION >= 52049000} // >= 52.49.0 + FF_QSCALE_TYPE_VP56 = 3; + {$IFEND} FF_BUFFER_TYPE_INTERNAL = 1; FF_BUFFER_TYPE_USER = 2; ///< Direct rendering buffers (image is (de)allocated by user) @@ -809,6 +953,9 @@ const FF_BUG_HPEL_CHROMA = 2048; FF_BUG_DC_CLIP = 4096; FF_BUG_MS = 8192; ///< workaround various bugs in microsofts broken decoders + {$IF LIBAVCODEC_VERSION >= 52054000} // >= 52.54.0 + FF_BUG_TRUNCATED = 16384; + {$IFEND} //FF_BUG_FAKE_SCALABILITY = 16 //Autodetection should work 100%. FF_COMPLIANCE_VERY_STRICT = 2; ///< strictly conform to a older more strict version of the spec or reference software @@ -854,6 +1001,9 @@ const FF_IDCT_EA = 21; FF_IDCT_SIMPLENEON = 22; FF_IDCT_SIMPLEALPHA = 23; + {$IF LIBAVCODEC_VERSION >= 52055000} // >= 52.55.0 + FF_IDCT_BINK = 24; + {$IFEND} FF_EC_GUESS_MVS = 1; FF_EC_DEBLOCK = 2; @@ -974,11 +1124,11 @@ const FF_COMPRESSION_DEFAULT = -1; +{$IF LIBAVCODEC_MAX_VERSION_MAJOR < 53} const AVPALETTE_SIZE = 1024; AVPALETTE_COUNT = 256; -{$IF LIBAVCODEC_MAX_VERSION_MAJOR < 53} type (** * AVPaletteControl @@ -1054,7 +1204,7 @@ type end; const - {$IF LIBAVCODEC_VERSION >= 52030002} // >= 52.30.2 + {$IF LIBAVCODEC_VERSION < 52030002} // < 52.30.2 PKT_FLAG_KEY = $0001; {$ELSE} AV_PKT_FLAG_KEY = $0001; @@ -1079,7 +1229,11 @@ type TQuadIntArray = array[0..3] of cint; // int (*func)(struct AVCodecContext *c2, void *arg) TExecuteFunc = function(c2: PAVCodecContext; arg: Pointer): cint; cdecl; - +{$IF LIBAVCODEC_VERSION >= 52037000} // >= 52.37.0 + // int (*func)(struct AVCodecContext *c2, void *arg, int jobnr, int threadnr) + TExecute2Func = function(c2: PAVCodecContext; arg: Pointer; jobnr: cint; threadnr: cint): cint; cdecl; +{$IFEND} + TAVClass = record class_name: PAnsiChar; (* actually passing a pointer to an AVCodecContext @@ -1088,6 +1242,23 @@ type of AVIn/OutputFormat *) item_name: function(): PAnsiChar; cdecl; option: PAVOption; + +{$IF LIBAVUTIL_VERSION >= 50015000} // 50.15.0 + (** + * LIBAVUTIL_VERSION with which this structure was created. + * This is used to allow fields to be added without requiring major + * version bumps everywhere. + *) + version: cint; +{$IFEND} + +{$IF LIBAVUTIL_VERSION >= 50015002} // 50.15.2 + (** + * Offset in the structure where log_level_offset is stored. + * 0 means there is no such variable + *) + log_level_offset_offset: cint; +{$IFEND} end; {** @@ -1283,7 +1454,8 @@ type *) dct_coeff: PsmallInt; (** - * motion referece frame index + * motion reference frame index + * the order in which these are stored can depend on the codec. * - encoding: Set by user. * - decoding: Set by libavcodec. *) @@ -1307,118 +1479,11 @@ type *) hwaccel_data_private: pointer; {$IFEND} + {$IF LIBAVCODEC_VERSION >= 52022000} // >= 52.22.0 hwaccel_picture_private: pointer; {$IFEND} - {$IF LIBAVCODEC_VERSION >= 51070000} // >= 51.70.0 - (** - * Bits per sample/pixel of internal libavcodec pixel/sample format. - * This field is applicable only when sample_fmt is SAMPLE_FMT_S32. - * - encoding: set by user. - * - decoding: set by libavcodec. - *) - bits_per_raw_sample: cint; - {$IFEND} - - {$IF LIBAVCODEC_VERSION >= 52002000} // >= 52.2.0 - (** - * Audio channel layout. - * - encoding: set by user. - * - decoding: set by libavcodec. - *) - channel_layout: cint64; - - (** - * Request decoder to use this channel layout if it can (0 for default) - * - encoding: unused - * - decoding: Set by user. - *) - request_channel_layout: cint64; - {$IFEND} - - {$IF LIBAVCODEC_VERSION >= 52004000} // >= 52.4.0 - (** - * Ratecontrol attempt to use, at maximum, <value> of what can be used without an underflow. - * - encoding: Set by user. - * - decoding: unused. - *) - rc_max_available_vbv_use: cfloat; - - (** - * Ratecontrol attempt to use, at least, <value> times the amount needed to prevent a vbv overflow. - * - encoding: Set by user. - * - decoding: unused. - *) - rc_min_vbv_overflow_use: cfloat; - {$IFEND} - {$IF LIBAVCODEC_VERSION >= 52018000} // >= 52.18.0 - (** - * Hardware accelerator in use - * - encoding: unused. - * - decoding: Set by libavcodec - *) - hwaccel: PAVHWAccel; - {$IFEND} - {$IF LIBAVCODEC_VERSION >= 52020000} // >= 52.20.0 - (** - * For some codecs, the time base is closer to the field rate than the frame rate. - * Most notably, H.264 and MPEG-2 specify time_base as half of frame duration - * if no telecine is used ... - * - * Set to time_base ticks per frame. Default 1, e.g., H.264/MPEG-2 set it to 2. - *) - ticks_per_frame: cint; - {$IFEND} - {$IF LIBAVCODEC_VERSION >= 52021000} // >= 52.21.0 - (** - * Hardware accelerator context. - * For some hardware accelerators, a global context needs to be - * provided by the user. In that case, this holds display-dependent - * data FFmpeg cannot instantiate itself. Please refer to the - * FFmpeg HW accelerator documentation to know how to fill this - * is. e.g. for VA API, this is a struct vaapi_context. - * - encoding: unused - * - decoding: Set by user - *) - hwaccel_context: pointer; - {$IFEND} - {$IF LIBAVCODEC_VERSION >= 52028000} // >= 52.28.0 - (** - * Chromaticity coordinates of the source primaries. - * - encoding: Set by user - * - decoding: Set by libavcodec - *) - color_primaries: TAVColorPrimaries; - - (** - * Color Transfer Characteristic. - * - encoding: Set by user - * - decoding: Set by libavcodec - *) - color_trc: TAVColorTransferCharacteristic; - - (** - * YUV colorspace type. - * - encoding: Set by user - * - decoding: Set by libavcodec - *) - colorspace: TAVColorSpace; - - (** - * MPEG vs JPEG YUV range. - * - encoding: Set by user - * - decoding: Set by libavcodec - *) - color_range: TAVColorRange; - - (** - * This defines the location of chroma samples. - * - encoding: Set by user - * - decoding: Set by libavcodec - *) - chroma_sample_location: TAVChromaLocation; - {$IFEND} end; (** @@ -1563,7 +1628,7 @@ type * - encoding: Set by user. * - decoding: Set by libavcodec. *) - sample_fmt: TSampleFormat; ///< sample format, currenly unused + sample_fmt: TSampleFormat; ///< sample format (* The following data should not be initialized. *) (** @@ -1689,7 +1754,11 @@ type opaque: pointer; codec_name: array [0..31] of AnsiChar; +{$IF LIBAVCODEC_VERSION < 52064000} // < 52.64.0 codec_type: TCodecType; (* see CODEC_TYPE_xxx *) +{$ELSE} + codec_type: TAVMediaType; (* see AVMEDIA_TYPE_xxx *) +{$IFEND} codec_id: TCodecID; (* see CODEC_ID_xxx *) (** @@ -1760,7 +1829,7 @@ type (** * Called at the beginning of each frame to get a buffer for it. * If pic.reference is set then the frame will be read later by libavcodec. - * avcodec_align_dimensions() should be used to find the required width and + * avcodec_align_dimensions2() should be used to find the required width and * height, as they normally need to be rounded up to the next multiple of 16. * if CODEC_CAP_DR1 is not set then get_buffer() must call * avcodec_default_get_buffer() instead of providing buffers allocated by @@ -2745,7 +2814,111 @@ type reordered_opaque: cint64; {$IFEND} - {$IF LIBAVCODEC_VERSION >= 52028000} // 52.28.0 + {$IF LIBAVCODEC_VERSION >= 51069000} // 51.69.0 + (** + * Bits per sample/pixel of internal libavcodec pixel/sample format. + * This field is applicable only when sample_fmt is SAMPLE_FMT_S32. + * - encoding: set by user. + * - decoding: set by libavcodec. + *) + bits_per_raw_sample: cint; + {$IFEND} + + {$IF LIBAVCODEC_VERSION >= 52002000} // 52.2.0 + (** + * Audio channel layout. + * - encoding: set by user. + * - decoding: set by libavcodec. + *) + channel_layout: cint64; + + (** + * Request decoder to use this channel layout if it can (0 for default) + * - encoding: unused + * - decoding: Set by user. + *) + request_channel_layout: cint64; + {$IFEND} + + {$IF LIBAVCODEC_VERSION >= 52004000} // >= 52.4.0 + (** + * Ratecontrol attempt to use, at maximum, <value> of what can be used without an underflow. + * - encoding: Set by user. + * - decoding: unused. + *) + rc_max_available_vbv_use: cfloat; + + (** + * Ratecontrol attempt to use, at least, <value> times the amount needed to prevent a vbv overflow. + * - encoding: Set by user. + * - decoding: unused. + *) + rc_min_vbv_overflow_use: cfloat; + {$IFEND} + + {$IF LIBAVCODEC_VERSION >= 52018000} // >= 52.18.0 + (** + * Hardware accelerator in use + * - encoding: unused. + * - decoding: Set by libavcodec + *) + hwaccel: PAVHWAccel; + {$IFEND} + + {$IF LIBAVCODEC_VERSION >= 52020000} // >= 52.20.0 + (** + * For some codecs, the time base is closer to the field rate than the frame rate. + * Most notably, H.264 and MPEG-2 specify time_base as half of frame duration + * if no telecine is used ... + * + * Set to time_base ticks per frame. Default 1, e.g., H.264/MPEG-2 set it to 2. + *) + ticks_per_frame: cint; + {$IFEND} + + {$IF LIBAVCODEC_VERSION >= 52021000} // >= 52.21.0 + (** + * Hardware accelerator context. + * For some hardware accelerators, a global context needs to be + * provided by the user. In that case, this holds display-dependent + * data FFmpeg cannot instantiate itself. Please refer to the + * FFmpeg HW accelerator documentation to know how to fill this + * is. e.g. for VA API, this is a struct vaapi_context. + * - encoding: unused + * - decoding: Set by user + *) + hwaccel_context: pointer; + {$IFEND} + + {$IF LIBAVCODEC_VERSION >= 52028000} // >= 52.28.0 + (** + * Chromaticity coordinates of the source primaries. + * - encoding: Set by user + * - decoding: Set by libavcodec + *) + color_primaries: TAVColorPrimaries; + + (** + * Color Transfer Characteristic. + * - encoding: Set by user + * - decoding: Set by libavcodec + *) + color_trc: TAVColorTransferCharacteristic; + + (** + * YUV colorspace type. + * - encoding: Set by user + * - decoding: Set by libavcodec + *) + colorspace: TAVColorSpace; + + (** + * MPEG vs JPEG YUV range. + * - encoding: Set by user + * - decoding: Set by libavcodec + *) + color_range: TAVColorRange; + (** * This defines the location of chroma samples. * - encoding: Set by user @@ -2753,6 +2926,95 @@ type *) chroma_sample_location: TAVChromaLocation; {$IFEND} + + {$IF LIBAVCODEC_VERSION >= 52037000} // >= 52.37.0 + (** + * The codec may call this to execute several independent things. + * It will return only after finishing all tasks. + * The user may replace this with some multithreaded implementation, + * the default implementation will execute the parts serially. + * Also see avcodec_thread_init and e.g. the --enable-pthread configure option. + * @param c context passed also to func + * @param count the number of things to execute + * @param arg2 argument passed unchanged to func + * @param ret return values of executed functions, must have space for "count" values. May be NULL. + * @param func function that will be called count times, with jobnr from 0 to count-1. + * threadnr will be in the range 0 to c->thread_count-1 < MAX_THREADS and so that no + * two instances of func executing at the same time will have the same threadnr. + * @return always 0 currently, but code should handle a future improvement where when any call to func + * returns < 0 no further calls to func may be done and < 0 is returned. + * - encoding: Set by libavcodec, user can override. + * - decoding: Set by libavcodec, user can override. + *) + execute2: function (c: PAVCodecContext; func: TExecute2Func; arg2: Pointer; ret: Pcint; count: cint): cint; cdecl; + {$IFEND} + + {$IF LIBAVCODEC_VERSION >= 52042000} // >= 52.42.0 + (** + * explicit P-frame weighted prediction analysis method + * 0: off + * 1: fast blind weighting (one reference duplicate with -1 offset) + * 2: smart weighting (full fade detection analysis) + * - encoding: Set by user. + * - decoding: unused + *) + weighted_p_pred: cint; + {$IFEND} + + {$IF LIBAVCODEC_VERSION >= 52061000} // >= 52.61.0 + (** + * AQ mode + * 0: Disabled + * 1: Variance AQ (complexity mask) + * 2: Auto-variance AQ (experimental) + * - encoding: Set by user + * - decoding: unused + *) + aq_mode: cint; + + (** + * AQ strength + * Reduces blocking and blurring in flat and textured areas. + * - encoding: Set by user + * - decoding: unused + *) + aq_strength: cfloat; + + (** + * PSY RD + * Strength of psychovisual optimization + * - encoding: Set by user + * - decoding: unused + *) + psy_rd: cfloat; + + (** + * PSY trellis + * Strength of psychovisual optimization + * - encoding: Set by user + * - decoding: unused + *) + psy_trellis: cfloat; + + (** + * RC lookahead + * Number of frames for frametype and ratecontrol lookahead + * - encoding: Set by user + * - decoding: unused + *) + rc_lookahead: cint; + {$IFEND} + + {$IF LIBAVCODEC_VERSION >= 52067000} // >= 52.67.0 + (** + * Constant rate factor maximum + * With CRF encoding mode and VBV restrictions enabled, prevents quality from being worse + * than crf_max, even if doing so would violate VBV restrictions. + * - encoding: Set by user. + * - decoding: unused + *) + crf_max: cfloat; + {$IFEND} end; (** @@ -2760,7 +3022,11 @@ type *) TAVCodec = record name: PAnsiChar; +{$IF LIBAVCODEC_VERSION < 52064000} // < 52.64.0 type_: TCodecType; +{$ELSE} + type_: TAVMediaType; +{$IFEND} id: TCodecID; priv_data_size: cint; init: function (avctx: PAVCodecContext): cint; cdecl; (* typo corretion by the Creative CAT *) @@ -2815,13 +3081,23 @@ type *) name: PAnsiChar; +{$IF LIBAVCODEC_VERSION < 52064000} // < 52.64.0 (** * Type of codec implemented by the hardware accelerator. * * See CODEC_TYPE_xxx *) type_: TCodecType; +{$ELSE} + (** + * Type of codec implemented by the hardware accelerator. + * + * See AVMediaType_xxx + *) + type_: TAVMediaType; +{$IFEND} + (** * Codec implemented by the hardware accelerator. * @@ -2983,6 +3259,9 @@ type {$ELSE} rects: PPAVSubtitleRect; {$IFEND} + {$IF LIBAVCODEC_VERSION >= 52032000} // >= 52.32.0 + pts: cint64; ///< Same as packet pts, in AV_TIME_BASE + {$IFEND} end; {$IF LIBAVCODEC_VERSION >= 52025000} // 52.25.0 @@ -3005,7 +3284,7 @@ procedure av_destruct_packet(pkt: PAVPacket); * * @param pkt packet *) -procedure av_init_packet(pkt: PAVPacket); +procedure av_init_packet(var pkt: TAVPacket); cdecl; external av__codec; (* @@ -3223,6 +3502,7 @@ function avcodec_get_pix_fmt_name(pix_fmt: TAVPixelFormat): PAnsiChar; procedure avcodec_set_dimensions(s: PAVCodecContext; width: cint; height: cint); cdecl; external av__codec; +{$IF LIBAVCODEC_MAX_VERSION_MAJOR < 53} (** * Returns the pixel format corresponding to the name name. * @@ -3232,12 +3512,22 @@ procedure avcodec_set_dimensions(s: PAVCodecContext; width: cint; height: cint); * For example in a little-endian system, first looks for "gray16", * then for "gray16le". * - * Finally if no pixel format has been found, returns PIX_FMT_NONE. + * Finally if no pixel format has been found, returns PIX_FMT_NONE.* + * @deprecated Deprecated in favor of av_get_pix_fmt(). *) function avcodec_get_pix_fmt(name: {const} PAnsiChar): TAVPixelFormat; cdecl; external av__codec; +{$IF LIBAVCODEC_VERSION >= 52049000} // >= 52.49.0 + deprecated; +{$IFEND} +{$IFEND} -function avcodec_pix_fmt_to_codec_tag(p: TAVPixelFormat): cuint; +(** + * Returns a value representing the fourCC code associated to the + * pixel format pix_fmt, or 0 if no associated fourCC code can be + * found. + *) +function avcodec_pix_fmt_to_codec_tag(pix_fmt: TAVPixelFormat): cuint; cdecl; external av__codec; const @@ -3390,6 +3680,20 @@ function avcodec_build(): cuint; cdecl; external av__codec; deprecated; {$IFEND} +{$IF LIBAVCODEC_VERSION >= 52041000} // 52.41.0 +(** + * Returns the libavcodec build-time configuration. + *) +function avcodec_configuration(): PAnsiChar; + cdecl; external av__codec; + +(** + * Returns the libavcodec license. + *) +function avcodec_license(): PAnsiChar; + cdecl; external av__codec; +{$IFEND} + (** * Initializes libavcodec. * @@ -3463,8 +3767,13 @@ procedure avcodec_get_context_defaults(s: PAVCodecContext); {$IF LIBAVCODEC_VERSION >= 51039000} // 51.39.0 (** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API! * we WILL change its arguments and name a few times! *) +{$IF LIBAVCODEC_VERSION < 52064000} // < 52.64.0 procedure avcodec_get_context_defaults2(s: PAVCodecContext; ctype: TCodecType); cdecl; external av__codec; +{$ELSE} +procedure avcodec_get_context_defaults2(s: PAVCodecContext; ctype: TAVMediaType); + cdecl; external av__codec; +{$IFEND} {$IFEND} (** @@ -3480,8 +3789,29 @@ function avcodec_alloc_context(): PAVCodecContext; {$IF LIBAVCODEC_VERSION >= 51039000} // 51.39.0 (** THIS FUNCTION IS NOT YET PART OF THE PUBLIC API! * we WILL change its arguments and name a few times! *) +{$IF LIBAVCODEC_VERSION < 52064000} // < 52.64.0 function avcodec_alloc_context2(ctype: TCodecType): PAVCodecContext; cdecl; external av__codec; +{$ELSE} +function avcodec_alloc_context2(ctype: TAVMediaType): PAVCodecContext; + cdecl; external av__codec; +{$IFEND} +{$IFEND} + +{$IF LIBAVCODEC_VERSION >= 52065000} // >= 52.65.0 +(** + * Copy the settings of the source AVCodecContext into the destination + * AVCodecContext. The resulting destination codec context will be + * unopened, i.e. you are required to call avcodec_open() before you + * can use this AVCodecContext to decode/encode video/audio data. + * + * @param dest target codec context, should be initialized with + * avcodec_alloc_context(), but otherwise uninitialized + * @param src source codec context + * @return AVERROR() on error (e.g. memory allocation error), 0 on success + *) +function avcodec_copy_context(dest: PAVCodecContext; src: {const} PAVCodecContext): cint; + cdecl; external av__codec; {$IFEND} (** @@ -3508,9 +3838,38 @@ procedure avcodec_default_release_buffer (s: PAVCodecContext; pic: PAVFrame); cdecl; external av__codec; function avcodec_default_reget_buffer (s: PAVCodecContext; pic: PAVFrame): cint; cdecl; external av__codec; + +{$IF LIBAVCODEC_VERSION >= 52066000} // >= 52.66.0 +(** + * Returns the amount of padding in pixels which the get_buffer callback must + * provide around the edge of the image for codecs which do not have the + * CODEC_FLAG_EMU_EDGE flag. + * + * @return Required padding in pixels. + *) +function avcodec_get_edge_width(): cuint; + cdecl; external av__codec; +{$IFEND} + +(** + * Modifies width and height values so that they will result in a memory + * buffer that is acceptable for the codec if you do not use any horizontal + * padding. + *) procedure avcodec_align_dimensions(s: PAVCodecContext; width: PCint; height: PCint); cdecl; external av__codec; +{$IF LIBAVCODEC_VERSION >= 52055000} // >= 52.55.0 +(** + * Modifies width and height values so that they will result in a memory + * buffer that is acceptable for the codec if you also ensure that all + * line sizes are a multiple of the respective linesize_align[i]. + *) +procedure avcodec_align_dimensions2(s: PAVCodecContext; width: PCint; height: PCint; + linesize_align: PQuadIntArray); + cdecl; external av__codec; +{$IFEND} + (** * Checks if the given dimension of a picture is valid, meaning that all * bytes of the picture can be addressed with a signed int. @@ -3529,11 +3888,10 @@ function avcodec_thread_init(s: PAVCodecContext; thread_count: cint): cint; procedure avcodec_thread_free(s: PAVCodecContext); cdecl; external av__codec; - {$IF LIBAVCODEC_VERSION < 52004000} // < 52.4.0 function avcodec_thread_execute(s: PAVCodecContext; func: TExecuteFunc; arg: PPointer; var ret: cint; count: cint): cint; cdecl; external av__codec; -{$ELSE} +{$ELSEIF LIBAVCODEC_VERSION < 52059000} // < 52.59.0 function avcodec_thread_execute(s: PAVCodecContext; func: TExecuteFunc; arg: Pointer; var ret: cint; count: cint; size: cint): cint; cdecl; external av__codec; {$IFEND} @@ -3545,6 +3903,11 @@ function avcodec_default_execute(s: PAVCodecContext; func: TExecuteFunc; arg: PP function avcodec_default_execute(s: PAVCodecContext; func: TExecuteFunc; arg: Pointer; var ret: cint; count: cint; size: cint): cint; cdecl; external av__codec; {$IFEND} + +{$IF LIBAVCODEC_VERSION >= 52037000} // >= 52.37.0 +function avcodec_default_execute2(s: PAVCodecContext; func: TExecuteFunc; arg: Pointer; var ret: cint; count: cint): cint; + cdecl; external av__codec; +{$IFEND} //FIXME func typedef (** @@ -3595,7 +3958,7 @@ function avcodec_decode_audio(avctx: PAVCodecContext; samples: PSmallint; * * @deprecated Use avcodec_decode_audio3 instead. * @param avctx the codec context - * @param[out] samples the output buffer + * @param[out] samples the output buffer, sample type in avctx->sample_fmt * @param[in,out] frame_size_ptr the output buffer size in bytes * @param[in] buf the input buffer * @param[in] buf_size the input buffer size in bytes @@ -3613,9 +3976,11 @@ function avcodec_decode_audio2(avctx: PAVCodecContext; samples: PSmallint; (** * Decodes the audio frame of size avpkt->size from avpkt->data into samples. * Some decoders may support multiple frames in a single AVPacket, such - * decoders would then just decode the first frame. + * decoders would then just decode the first frame. In this case, + * avcodec_decode_audio3 has to be called again with an AVPacket that contains + * the remaining data in order to decode the second frame etc. * If no frame - * could be decompressed, frame_size_ptr is zero. Otherwise, it is the + * could be outputted, frame_size_ptr is zero. Otherwise, it is the * decompressed frame size in bytes. * * @warning You must set frame_size_ptr to the allocated size of the @@ -3638,7 +4003,7 @@ function avcodec_decode_audio2(avctx: PAVCodecContext; samples: PSmallint; * (AltiVec and SSE do). * * @note Some codecs have a delay between input and output, these need to be - * feeded with avpkt->data=NULL, avpkt->size=0 at the end to return the remaining frames. + * fed with avpkt->data=NULL, avpkt->size=0 at the end to return the remaining frames. * * @param avctx the codec context * @param[out] samples the output buffer @@ -3648,7 +4013,7 @@ function avcodec_decode_audio2(avctx: PAVCodecContext; samples: PSmallint; * data and size, some decoders might in addition need other fields. * All decoders are designed to use the least fields possible though. * @return On error a negative value is returned, otherwise the number of bytes - * used or zero if no frame could be decompressed. + * used or zero if no frame data was decompressed (used) from the input AVPacket. *) function avcodec_decode_audio3(avctx: PAVCodecContext; samples: PSmallint; var frame_size_ptr: cint; @@ -3664,6 +4029,8 @@ function avcodec_decode_audio3(avctx: PAVCodecContext; samples: PSmallint; * @deprecated Use avcodec_decode_video2 instead. * @param avctx the codec context * @param[out] picture The AVFrame in which the decoded video frame will be stored. + * Use avcodec_alloc_frame to get an AVFrame, the codec will + * allocate memory for the actual bitmap. * @param[in] buf the input buffer * @param[in] buf_size the size of the input buffer in bytes * @param[in,out] got_picture_ptr Zero if no frame could be decompressed, otherwise, it is nonzero. @@ -3701,7 +4068,7 @@ function avcodec_decode_video(avctx: PAVCodecContext; picture: PAVFrame; * @param[in] avpkt The input AVpacket containing the input buffer. * You can create such packet with av_init_packet() and by then setting * data and size, some decoders might in addition need other fields like - * flags&PKT_FLAG_KEY. All decoders are designed to use the least + * flags&AV_PKT_FLAG_KEY. All decoders are designed to use the least * fields possible. * @param[in,out] got_picture_ptr Zero if no frame could be decompressed, otherwise, it is nonzero. * @return On error a negative value is returned, otherwise the number of bytes @@ -3987,9 +4354,10 @@ type codec_ids: array [0..4] of cint; (* several codec IDs are permitted *) priv_data_size: cint; parser_init: function(s: PAVCodecParserContext): cint; cdecl; - parser_parse: function(s: PAVCodecParserContext; avctx: PAVCodecContext; - poutbuf: {const} PPointer; poutbuf_size: PCint; - buf: {const} PByteArray; buf_size: cint): cint; cdecl; + parser_parse: function(s: PAVCodecParserContext; + avctx: PAVCodecContext; + poutbuf: {const} PPointer; poutbuf_size: PCint; + buf: {const} PByteArray; buf_size: cint): cint; cdecl; parser_close: procedure(s: PAVCodecParserContext); cdecl; split: function(avctx: PAVCodecContext; buf: {const} PByteArray; buf_size: cint): cint; cdecl; @@ -4112,6 +4480,7 @@ function av_bitstream_filter_filter(bsfc: PAVBitStreamFilterContext; poutbuf: PPointer; poutbuf_size: PCint; buf: PByte; buf_size: cint; keyframe: cint): cint; cdecl; external av__codec; + procedure av_bitstream_filter_close(bsf: PAVBitStreamFilterContext); cdecl; external av__codec; @@ -4255,6 +4624,13 @@ function img_pad(dst: PAVPicture; src: {const} PAVPicture; height, width: cint; cdecl; external av__codec; deprecated; {$IFEND} +(** + * Encodes extradata length to a buffer. Used by xiph codecs. + * + * @param s buffer to write to; must be at least (v/255+1) bytes long + * @param v size of extradata in bytes + * @return number of bytes written to the buffer. + *) function av_xiphlacing(s: PByte; v: cuint): cuint; cdecl; external av__codec; @@ -4286,6 +4662,13 @@ function av_parse_video_frame_rate(frame_rate: PAVRational; str: {const} PAnsiCh cdecl; external av__codec; {$IFEND} +{$IF LIBAVCODEC_VERSION < 52059000} // <52.59.0 + +{ + The following error codes are moved to libavutil/error.h on + revision 22501 Mar 13 2010 +} + {* error handling *} const @@ -4313,13 +4696,20 @@ const {$ENDIF} {$ENDIF} +(** + * We need the sign of the error, because some platforms have + * E* and errno already negated. The previous version failed + * with Delphi, because it needed EINVAL defined. + * Warning: This code is platform dependent and assumes constants + * to be 32 bit. + * This version does the following steps: + * 1) shr 30: shifts the sign bit to bit position 2 + * 2) and $00000002: sets all other bits to zero + * positive EINVAL gives 0, negative gives 2 + * 3) - 1: positive EINVAL gives -1, negative 1 + *) const -{$IF EINVAL > 0} - AVERROR_SIGN = -1; -{$ELSE} - {* Some platforms have E* and errno already negated. *} - AVERROR_SIGN = 1; -{$IFEND} + AVERROR_SIGN = (EINVAL shr 30) and $00000002 - 1; (* #if EINVAL > 0 @@ -4347,6 +4737,35 @@ const // Note: function calls as constant-initializers are invalid //AVERROR_PATCHWELCOME = -MKTAG('P','A','W','E'); {**< Not yet implemented in FFmpeg. Patches welcome. *} AVERROR_PATCHWELCOME = -(ord('P') or (ord('A') shl 8) or (ord('W') shl 16) or (ord('E') shl 24)); +{$IFEND} + +{$IF LIBAVCODEC_VERSION >= 52032000} // >= 52.32.0 +(** + * Logs a generic warning message about a missing feature. This function is + * intended to be used internally by FFmpeg (libavcodec, libavformat, etc.) + * only, and would normally not be used by applications. + * @param[in] avc a pointer to an arbitrary struct of which the first field is + * a pointer to an AVClass struct + * @param[in] feature string containing the name of the missing feature + * @param[in] want_sample indicates if samples are wanted which exhibit this feature. + * If want_sample is non-zero, additional verbage will be added to the log + * message which tells the user how to report samples to the development + * mailing list. + *) +procedure av_log_missing_feature(avc: Pointer; feature: {const} Pchar; want_sample: cint); + cdecl; external av__codec; + +(** + * Logs a generic warning message asking for a sample. This function is + * intended to be used internally by FFmpeg (libavcodec, libavformat, etc.) + * only, and would normally not be used by applications. + * @param[in] avc a pointer to an arbitrary struct of which the first field is + * a pointer to an AVClass struct + * @param[in] msg string containing an optional message, or NULL if no message + *) +procedure av_log_ask_for_sample(avc: Pointer; msg: {const} Pchar); + cdecl; external av__codec; +{$IFEND} {$IF LIBAVCODEC_VERSION >= 52018000} // 52.18.0 (** @@ -4396,18 +4815,15 @@ type implementation -{$IF (LIBAVCODEC_VERSION >= 52025000) and (LIBAVCODEC_VERSION <= 5202700)} // 52.25.0 +{$IF (LIBAVCODEC_VERSION >= 52025000) and (LIBAVCODEC_VERSION <= 52027000)} // 52.25.0 - 52.27.0 procedure av_free_packet(pkt: PAVPacket);{$IFDEF HASINLINE} inline; {$ENDIF} begin - if (pkt <> nil) then + if assigned(pkt) then begin - if (pkt.destruct <> nil) then - pkt.destruct(pkt) - else - begin - pkt.data = NULL; - pkt.size = 0; - end; + if assigned(pkt^.destruct) then + pkt^.destruct(pkt); + pkt^.data := NIL; + pkt^.size := 0; end; end; {$IFEND} diff --git a/cmake/src/lib/ffmpeg/avformat.pas b/cmake/src/lib/ffmpeg/avformat.pas index 0ec2c118..b745f962 100644 --- a/cmake/src/lib/ffmpeg/avformat.pas +++ b/cmake/src/lib/ffmpeg/avformat.pas @@ -26,14 +26,9 @@ (* * Conversion of libavformat/avformat.h - * Min. version: 50.5.0 , revision 6577, Sat Oct 7 15:30:46 2006 UTC - * Max. version: 52.25.0, revision 16986, Wed Feb 4 05:56:39 2009 UTC + * Min. version: 50.5.0 , revision 6577, Sat Oct 7 15:30:46 2006 UTC + * Max. version: 52.63.0, revision 23179, Wed May 19 19:17:00 2010 CET *) -{ - * update to - * Max. version: 52.34.0, Sat Jun 13 00:37:00 2009 UTC - * MiSchi -} unit avformat; @@ -63,9 +58,34 @@ uses UConfig; const + (* + * IMPORTANT: The official FFmpeg C headers change very quickly. Often some + * of the data structures are changed so that they become incompatible with + * older header files. The Pascal headers have to be adjusted to those changes, + * otherwise the application might crash randomly or strange bugs (not + * necessarily related to video or audio due to buffer overflows etc.) might + * occur. + * + * In the past users reported problems with USDX that took hours to fix and + * the problem was an unsupported version of FFmpeg. So we decided to disable + * support for future versions of FFmpeg until the headers are revised by us + * for that version as they otherwise most probably will break USDX. + * + * If the headers do not yet support your FFmpeg version you may want to + * adjust the max. version numbers manually but please note: it may work but + * in many cases it does not. The USDX team does NOT PROVIDE ANY SUPPORT + * for the game if the MAX. VERSION WAS CHANGED. + * + * The only safe way to support new versions of FFmpeg is to add the changes + * of the FFmpeg git repository C headers to the Pascal headers. + * You can accelerate this process by posting a patch with the git changes + * translated to Pascal to our bug tracker (please join our IRC chat before + * you start working on it). Simply adjusting the max. versions is NOT a valid + * fix. + *) (* Max. supported version by this header *) LIBAVFORMAT_MAX_VERSION_MAJOR = 52; - LIBAVFORMAT_MAX_VERSION_MINOR = 34; + LIBAVFORMAT_MAX_VERSION_MINOR = 63; LIBAVFORMAT_MAX_VERSION_RELEASE = 0; LIBAVFORMAT_MAX_VERSION = (LIBAVFORMAT_MAX_VERSION_MAJOR * VERSION_MAJOR) + (LIBAVFORMAT_MAX_VERSION_MINOR * VERSION_MINOR) + @@ -91,19 +111,36 @@ const {$IF LIBAVFORMAT_VERSION >= 52020000} // 52.20.0 (** - * Returns the LIBAVFORMAT_VERSION_INT constant. + * I return the LIBAVFORMAT_VERSION_INT constant. You got + * a fucking problem with that, douchebag? *) function avformat_version(): cuint; cdecl; external av__format; {$IFEND} +{$IF LIBAVFORMAT_VERSION >= 52039002} // 52.39.2 +(** + * Returns the libavformat build-time configuration. + *) +function avformat_configuration(): {const} PansiChar; + cdecl; external av__format; + +(** + * Returns the libavformat license. + *) +function avformat_license(): {const} PansiChar; + cdecl; external av__format; +{$IFEND} + type PAVFile = Pointer; (* * Public Metadata API. * The metadata API allows libavformat to export metadata tags to a client - * application using a sequence of key/value pairs. + * application using a sequence of key/value pairs. Like all strings in FFmpeg, + * metadata must be stored as UTF-8 encoded Unicode. Note that metadata + * exported by demuxers isn't checked to be valid UTF-8 in most cases. * Important concepts to keep in mind: * 1. Keys are unique; there can never be 2 tags with the same key. This is * also meant semantically, i.e., a demuxer should not knowingly produce @@ -122,6 +159,13 @@ type const AV_METADATA_MATCH_CASE = 1; AV_METADATA_IGNORE_SUFFIX = 2; +{$IF LIBAVFORMAT_VERSION >= 52043000} // >= 52.43.0 + AV_METADATA_DONT_STRDUP_KEY = 4; + AV_METADATA_DONT_STRDUP_VAL = 8; +{$IFEND} +{$IF LIBAVFORMAT_VERSION >= 52061000} // >= 52.61.0 + AV_METADATA_DONT_OVERWRITE = 16; +{$IFEND} type PAVMetadataTag = ^TAVMetadataTag; @@ -133,9 +177,11 @@ type PAVMetadata = Pointer; {$IF LIBAVFORMAT_VERSION > 52024001} // > 52.24.1 +{$IF LIBAVFORMAT_VERSION_MAJOR = 52} (** * Gets a metadata element with matching key. * @param prev Set to the previous matching element to find the next. + * If set to NULL the first matching element is returned. * @param flags Allows case as well as suffix-insensitive comparisons. * @return Found tag or NULL, changing key or value leads to undefined behavior. *) @@ -148,9 +194,25 @@ function av_metadata_get(m: PAVMetadata; key: {const} PAnsiChar; * @param key tag key to add to m (will be av_strduped) * @param value tag value to add to m (will be av_strduped) * @return >= 0 on success otherwise an error code <0 + * @deprecated Use av_metadata_set2() instead. *) function av_metadata_set(var pm: PAVMetadata; key: {const} PAnsiChar; value: {const} PAnsiChar): cint; cdecl; external av__format; +{$IF LIBAVFORMAT_VERSION >= 52061000} // >= 52.61.0 + deprecated; +{$IFEND} +{$IFEND} + +{$IF LIBAVFORMAT_VERSION >= 52043000} // >= 52.43.0 +(** + * Sets the given tag in m, overwriting an existing tag. + * @param key tag key to add to m (will be av_strduped depending on flags) + * @param value tag value to add to m (will be av_strduped depending on flags) + * @return >= 0 on success otherwise an error code <0 + *) +function av_metadata_set2(var pm: PAVMetadata; key: {const} PAnsiChar; value: {const} PAnsiChar; flags: cint): cint; + cdecl; external av__format; +{$IFEND} (** * Frees all the memory allocated for an AVMetadata struct. @@ -161,7 +223,7 @@ procedure av_metadata_free(var m: PAVMetadata); (* packet functions *) -{$IF LIBAVCODEC_VERSION < 52032000} // < 52.32.0 +{$IF LIBAVFORMAT_VERSION < 52032000} // < 52.32.0 type PAVPacket = ^TAVPacket; TAVPacket = record @@ -259,7 +321,7 @@ function av_new_packet(var pkt: TAVPacket; size: cint): cint; function av_get_packet(s: PByteIOContext; var pkt: TAVPacket; size: cint): cint; cdecl; external av__format; -{$IF LIBAVCODEC_VERSION < 52032000} // < 52.32.0 +{$IF LIBAVFORMAT_VERSION < 52032000} // < 52.32.0 (** * @warning This is a hack - the packet memory allocation stuff is broken. The * packet is allocated if it was not really allocated. @@ -295,8 +357,8 @@ type (** This structure contains the data a format has to probe a file. *) TAVProbeData = record filename: PAnsiChar; - buf: PByteArray; - buf_size: cint; + buf: PByteArray; (**< Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero. *) + buf_size: cint; (**< Size of buf except extra allocated bytes *) end; const @@ -316,19 +378,36 @@ const {$IF LIBAVFORMAT_VERSION >= 52029002} // 52.29.2 AVFMT_VARIABLE_FPS = $0400; (**< Format allows variable fps. *) {$IFEND} + {$IF LIBAVFORMAT_VERSION >= 52052000} // 52.52.0 + AVFMT_NODIMENSIONS = $0800; (**< Format does not need width/height *) + {$IFEND} // used by AVIndexEntry AVINDEX_KEYFRAME = $0001; AVFMTCTX_NOHEADER = $0001; (**< signal that no header is present (streams are added dynamically) *) +{$IF LIBAVFORMAT_VERSION_MAJOR < 53} MAX_STREAMS = 20; +{$ELSE} + MAX_STREAMS = 100; +{$IFEND} AVFMT_NOOUTPUTLOOP = -1; AVFMT_INFINITEOUTPUTLOOP = 0; AVFMT_FLAG_GENPTS = $0001; ///< Generate missing pts even if it requires parsing future frames. AVFMT_FLAG_IGNIDX = $0002; ///< Ignore index. AVFMT_FLAG_NONBLOCK = $0004; ///< Do not block when reading packets from input. +{$IF LIBAVFORMAT_VERSION >= 52048000} // >= 52.48.0 + AVFMT_FLAG_IGNDTS = $0008; ///< Ignore DTS on frames that contain both DTS & PTS +{$IFEND} +{$IF LIBAVFORMAT_VERSION >= 52060000} // >= 52.60.0 + AVFMT_FLAG_NOFILLIN = $0010; ///< Do not infer any values from other values, just return what is stored in the container + AVFMT_FLAG_NOPARSE = $0020; ///< Do not use AVParsers, you also must set AVFMT_FLAG_NOFILLIN as the fillin code works on frames and no parsing -> no frames. Also seeking to frames can not work if parsing to find frame boundaries has been disabled +{$IFEND} +{$IF LIBAVFORMAT_VERSION >= 52063000} // >= 52.63.0 + AVFMT_FLAG_RTP_HINT = $0040; ///< Add RTP hinting to the output file +{$IFEND} // used by AVStream MAX_REORDER_DELAY = 16; @@ -347,8 +426,20 @@ const // used by TAVFormatContext.debug FF_FDEBUG_TS = 0001; - {$IF LIBAVFORMAT_VERSION >= 52034000} // > 52.34.0 + {$IF LIBAVFORMAT_VERSION >= 52034000} // >= 52.34.0 + {$IF LIBAVFORMAT_VERSION < 52039000} // < 52.39.0 MAX_PROBE_PACKETS = 100; + {$ELSE} + MAX_PROBE_PACKETS = 2500; + {$IFEND} + {$IFEND} + + {$IF LIBAVFORMAT_VERSION >= 52035000} // >= 52.35.0 + {$IF LIBAVFORMAT_VERSION < 52039000} // < 52.39.0 + RAW_PACKET_BUFFER_SIZE = 32000; + {$ELSE} + RAW_PACKET_BUFFER_SIZE = 2500000; + {$IFEND} {$IFEND} type @@ -543,11 +634,11 @@ type (** General purpose read-only value that the format can use. *) value: cint; - (** Start/resume playing - only meaningful if using a network-based format + (** Starts/resumes playing - only meaningful if using a network-based format (RTSP). *) read_play: function (c: PAVFormatContext): cint; cdecl; - (** Pause playing - only meaningful if using a network-based format + (** Pauses playing - only meaningful if using a network-based format (RTSP). *) read_pause: function (c: PAVFormatContext): cint; cdecl; @@ -557,7 +648,7 @@ type {$IF LIBAVFORMAT_VERSION >= 52030000} // 52.30.0 (** - * Seek to timestamp ts. + * Seeks to timestamp ts. * Seeking will be done so that the point from which all active streams * can be presented successfully will be closest to ts and within min/max_ts. * Active streams are all streams that have AVStream.discard < AVDISCARD_ALL. @@ -724,13 +815,32 @@ type *) reference_dts: cint64; {$IFEND} - {$IF LIBAVFORMAT_VERSION >= 52034000} // > 52.34.0 + {$IF LIBAVFORMAT_VERSION >= 52034000} // >= 52.34.0 (** * Number of packets to buffer for codec probing * NOT PART OF PUBLIC API *) probe_packets: cint; {$IFEND} + {$IF LIBAVFORMAT_VERSION >= 52038000} // >= 52.38.0 + (** + * last packet in packet_buffer for this stream when muxing. + * used internally, NOT PART OF PUBLIC API, dont read or write from outside of libav* + *) + last_in_packet_buffer: PAVPacketList; + {$IFEND} + {$IF LIBAVFORMAT_VERSION >= 52041000} // >= 52.41.0 + (** + * Average framerate + *) + avg_frame_rate: TAVRational; + {$IFEND} + {$IF LIBAVFORMAT_VERSION >= 52054000} // >= 52.54.0 + (** + * Number of frames that have been demuxed during av_find_stream_info() + *) + codec_info_nb_frames: cint; + {$IFEND} end; (** @@ -781,8 +891,9 @@ type It is deduced from the AVStream values. *) start_time: cint64; (** Decoding: duration of the stream, in AV_TIME_BASE fractional - seconds. NEVER set this value directly: it is deduced from the - AVStream values. *) + seconds. Only set this value if you know none of the individual stream + durations and also dont set any of them. This is deduced from the + AVStream values if not set. *) duration: cint64; (** decoding: total file size, 0 if unknown *) file_size: cint64; @@ -804,7 +915,11 @@ type index_built: cint; mux_rate: cint; + {$IF LIBAVFORMAT_VERSION < 52034001} // < 52.34.1 packet_size: cint; + {$ELSE} + packet_size: cuint; + {$IFEND} preload: cint; max_delay: cint; @@ -903,6 +1018,26 @@ type {$IF LIBAVFORMAT_VERSION >= 52024001} // 52.24.1 metadata: PAVMetadata; {$IFEND} + + {$IF LIBAVFORMAT_VERSION >= 52035000} // 52.35.0 + (** + * Remaining size available for raw_packet_buffer, in bytes. + * NOT PART OF PUBLIC API + *) + raw_packet_buffer_remaining_size: cint; + {$IFEND} + + {$IF LIBAVFORMAT_VERSION >= 52056000} // 52.56.0 + (** + * Start time of the stream in real world time, in microseconds + * since the unix epoch (00:00 1st January 1970). That is, pts=0 + * in the stream was captured at this real world time. + * - encoding: Set by user. + * - decoding: Unused. + *) + start_time_realtime: cint64; + {$IFEND} + end; (** @@ -1019,15 +1154,39 @@ procedure av_register_input_format(format: PAVInputFormat); procedure av_register_output_format(format: PAVOutputFormat); cdecl; external av__format; +{$IF LIBAVFORMAT_VERSION_MAJOR < 53} // < 53 function guess_stream_format(short_name: PAnsiChar; filename: PAnsiChar; mime_type: PAnsiChar): PAVOutputFormat; - cdecl; external av__format; + cdecl; external av__format; deprecated; +{$IFEND} +(** + * Returns the output format in the list of registered output formats + * which best matches the provided parameters, or returns NULL if + * there is no match. + * + * @param short_name if non-NULL checks if short_name matches with the + * names of the registered formats + * @param filename if non-NULL checks if filename terminates with the + * extensions of the registered formats + * @param mime_type if non-NULL checks if mime_type matches with the + * MIME type of the registered formats + *) +(** + * @deprecated Use av_guess_format() instead. + *) function guess_format(short_name: PAnsiChar; filename: PAnsiChar; mime_type: PAnsiChar): PAVOutputFormat; cdecl; external av__format; +{$IF LIBAVFORMAT_VERSION >= 52045000} // >= 52.45.0 + deprecated; +function av_guess_format(short_name: PAnsiChar; + filename: PAnsiChar; + mime_type: PAnsiChar): PAVOutputFormat; + cdecl; external av__format; +{$IFEND} (** * Guesses the codec ID based upon muxer and filename. @@ -1038,7 +1197,7 @@ function av_guess_codec(fmt: PAVOutputFormat; short_name: PAnsiChar; cdecl; external av__format; (** - * Send a nice hexadecimal dump of a buffer to the specified file stream. + * Sends a nice hexadecimal dump of a buffer to the specified file stream. * * @param f The file stream pointer where the dump should be sent to. * @param buf buffer @@ -1051,7 +1210,7 @@ procedure av_hex_dump(f: PAVFile; buf: PByteArray; size: cint); {$IF LIBAVFORMAT_VERSION >= 51011000} // 51.11.0 (** - * Send a nice hexadecimal dump of a buffer to the log. + * Sends a nice hexadecimal dump of a buffer to the log. * * @param avcl A pointer to an arbitrary struct of which the first field is a * pointer to an AVClass struct. @@ -1067,7 +1226,7 @@ procedure av_hex_dump_log(avcl: Pointer; level: cint; buf: PByteArray; size: cin {$IFEND} (** - * Send a nice dump of a packet to the specified file stream. + * Sends a nice dump of a packet to the specified file stream. * * @param f The file stream pointer where the dump should be sent to. * @param pkt packet to dump @@ -1078,7 +1237,7 @@ procedure av_pkt_dump(f: PAVFile; pkt: PAVPacket; dump_payload: cint); {$IF LIBAVFORMAT_VERSION >= 51011000} // 51.11.0 (** - * Send a nice dump of a packet to the log. + * Sends a nice dump of a packet to the log. * * @param avcl A pointer to an arbitrary struct of which the first field is a * pointer to an AVClass struct. @@ -1092,7 +1251,7 @@ procedure av_pkt_dump_log(avcl: Pointer; level: cint; pkt: PAVPacket; dump_paylo {$IFEND} (** - * Initialize libavformat and register all the muxers, demuxers and + * Initializes libavformat and registers all the muxers, demuxers and * protocols. If you do not call this function, then you can select * exactly which formats you want to support. * @@ -1104,9 +1263,23 @@ procedure av_register_all(); cdecl; external av__format; {$IF LIBAVFORMAT_VERSION >= 51008000} // 51.8.0 -(** codec tag <-> codec id *) +(** + * Gets the CodecID for the given codec tag tag. + * If no codec id is found returns CODEC_ID_NONE. + * + * @param tags list of supported codec_id-codec_tag pairs, as stored + * in AVInputFormat.codec_tag and AVOutputFormat.codec_tag + *) function av_codec_get_id(var tags: PAVCodecTag; tag: cuint): TCodecID; cdecl; external av__format; + +(** + * Gets the codec tag for the given codec id id. + * If no codec tag is found returns 0. + * + * @param tags list of supported codec_id-codec_tag pairs, as stored + * in AVInputFormat.codec_tag and AVOutputFormat.codec_tag + *) function av_codec_get_tag(var tags: PAVCodecTag; id: TCodecID): cuint; cdecl; external av__format; {$IFEND} @@ -1120,7 +1293,7 @@ function av_find_input_format(short_name: PAnsiChar): PAVInputFormat; cdecl; external av__format; (** - * Guess file format. + * Guesses file format. * * @param is_opened Whether the file is already opened; determines whether * demuxers with or without AVFMT_NOFILE are probed. @@ -1128,17 +1301,33 @@ function av_find_input_format(short_name: PAnsiChar): PAVInputFormat; function av_probe_input_format(pd: PAVProbeData; is_opened: cint): PAVInputFormat; cdecl; external av__format; +{$IF LIBAVFORMAT_VERSION >= 52062000} // 52.62.0 +(** + * Guesses the file format. + * + * @param is_opened Whether the file is already opened; determines whether + * demuxers with or without AVFMT_NOFILE are probed. + * @param score_max A probe score larger that this is required to accept a + * detection, the variable is set to the actual detection + * score afterwards. + * If the score is <= AVPROBE_SCORE_MAX / 4 it is recommended + * to retry with a larger probe buffer. + *) +function av_probe_input_format2(pd: PAVProbeData; is_opened: cint; score_max: PCint): PAVInputFormat; + cdecl; external av__format; +{$IFEND} + (** * Allocates all the structures needed to read an input stream. * This does not open the needed codecs for decoding the stream[s]. *) -function av_open_input_stream(ic_ptr: PAVFormatContext; +function av_open_input_stream(var ic_ptr: PAVFormatContext; pb: PByteIOContext; filename: PAnsiChar; fmt: PAVInputFormat; ap: PAVFormatParameters): cint; cdecl; external av__format; (** - * Open a media file as input. The codecs are not opened. Only the file + * Opens a media file as input. The codecs are not opened. Only the file * header (if present) is read. * * @param ic_ptr The opened media file handle is put here. @@ -1156,7 +1345,7 @@ function av_open_input_file(var ic_ptr: PAVFormatContext; filename: PAnsiChar; {$IF LIBAVFORMAT_VERSION >= 52026000} // 52.26.0 (** - * Allocate an AVFormatContext. + * Allocates an AVFormatContext. * Can be freed with av_free() but do not forget to free everything you * explicitly allocated as well! *) @@ -1173,7 +1362,7 @@ function av_alloc_format_context(): PAVFormatContext; {$IFEND} (** - * Read packets of a media file to get stream information. This + * Reads packets of a media file to get stream information. This * is useful for file formats with no headers such as MPEG. This * function also computes the real framerate in case of MPEG-2 repeat * frame mode. @@ -1189,7 +1378,7 @@ function av_find_stream_info(ic: PAVFormatContext): cint; cdecl; external av__format; (** - * Read a transport packet from a media file. + * Reads a transport packet from a media file. * * This function is obsolete and should never be used. * Use av_read_frame() instead. @@ -1202,7 +1391,7 @@ function av_read_packet(s: PAVFormatContext; var pkt: TAVPacket): cint; cdecl; external av__format; (** - * Return the next frame of a stream. + * Returns the next frame of a stream. * * The returned packet is valid * until the next av_read_frame() or until av_close_input_file() and @@ -1224,7 +1413,7 @@ function av_read_frame(s: PAVFormatContext; var pkt: TAVPacket): cint; cdecl; external av__format; (** - * Seek to the keyframe at timestamp. + * Seeks to the keyframe at timestamp. * 'timestamp' in 'stream_index'. * @param stream_index If stream_index is (-1), a default * stream is selected, and timestamp is automatically converted @@ -1240,7 +1429,7 @@ function av_seek_frame(s: PAVFormatContext; stream_index: cint; timestamp: cint6 {$IF LIBAVFORMAT_VERSION >= 52026000} // 52.26.0 (** - * Seek to timestamp ts. + * Seeks to timestamp ts. * Seeking will be done so that the point from which all active streams * can be presented successfully will be closest to ts and within min/max_ts. * Active streams are all streams that have AVStream.discard < AVDISCARD_ALL. @@ -1259,7 +1448,7 @@ function av_seek_frame(s: PAVFormatContext; stream_index: cint; timestamp: cint6 * @param ts target timestamp * @param max_ts largest acceptable timestamp * @param flags flags - * @returns >=0 on success, error code otherwise + * @return >=0 on success, error code otherwise * * @NOTE This is part of the new seek API which is still under construction. * Thus do not use this yet. It may change at any time, do not expect @@ -1275,14 +1464,14 @@ function avformat_seek_file(s: PAVFormatContext; {$IFEND} (** - * Start playing a network-based stream (e.g. RTSP stream) at the + * Starts playing a network-based stream (e.g. RTSP stream) at the * current position. *) function av_read_play(s: PAVFormatContext): cint; cdecl; external av__format; (** - * Pause a network-based stream (e.g. RTSP stream). + * Pauses a network-based stream (e.g. RTSP stream). * * Use av_read_play() to resume it. *) @@ -1291,7 +1480,7 @@ function av_read_pause(s: PAVFormatContext): cint; {$IF LIBAVFORMAT_VERSION >= 52003000} // 52.3.0 (** - * Free a AVFormatContext allocated by av_open_input_stream. + * Frees a AVFormatContext allocated by av_open_input_stream. * @param s context to free *) procedure av_close_input_stream(s: PAVFormatContext); @@ -1299,7 +1488,7 @@ procedure av_close_input_stream(s: PAVFormatContext); {$IFEND} (** - * Close a media file (but not its codecs). + * Closes a media file (but not its codecs). * * @param s media file handle *) @@ -1307,7 +1496,7 @@ procedure av_close_input_file(s: PAVFormatContext); cdecl; external av__format; (** - * Add a new stream to a media file. + * Adds a new stream to a media file. * * Can only be called in the read_header() function. If the flag * AVFMTCTX_NOHEADER is in the format context, then new streams @@ -1325,7 +1514,7 @@ function av_new_program(s: PAVFormatContext; id: cint): PAVProgram; {$IF LIBAVFORMAT_VERSION >= 52014000} // 52.14.0 (** - * Add a new chapter. + * Adds a new chapter. * This function is NOT part of the public API * and should ONLY be used by demuxers. * @@ -1343,7 +1532,7 @@ function ff_new_chapter(s: PAVFormatContext; id: cint; time_base: TAVRational; {$IFEND} (** - * Set the pts for a given stream. + * Sets the pts for a given stream. * * @param s stream * @param pts_wrap_bits number of bits effectively used by the pts @@ -1352,13 +1541,20 @@ function ff_new_chapter(s: PAVFormatContext; id: cint; time_base: TAVRational; * @param pts_den denominator to convert to seconds (MPEG: 90000) *) procedure av_set_pts_info(s: PAVStream; pts_wrap_bits: cint; +{$IF LIBAVFORMAT_VERSION < 52036000} // < 52.36.0 pts_num: cint; pts_den: cint); +{$ELSE} + pts_num: cuint; pts_den: cuint); +{$IFEND} cdecl; external av__format; const AVSEEK_FLAG_BACKWARD = 1; ///< seek backward AVSEEK_FLAG_BYTE = 2; ///< seeking based on position in bytes AVSEEK_FLAG_ANY = 4; ///< seek to any frame, even non-keyframes +{$IF LIBAVFORMAT_VERSION >= 52037000} // >= 52.37.0 + AVSEEK_FLAG_FRAME = 8; +{$IFEND} function av_find_default_stream_index(s: PAVFormatContext): cint; cdecl; external av__format; @@ -1387,7 +1583,7 @@ procedure ff_reduce_index(s: PAVFormatContext; stream_index: cint); {$IFEND} (** - * Add an index entry into a sorted list. Update the entry if the list + * Adds an index entry into a sorted list. Updates the entry if the list * already contains it. * * @param timestamp timestamp in the timebase of the given stream @@ -1447,7 +1643,7 @@ function av_set_parameters(s: PAVFormatContext; ap: PAVFormatParameters): cint; cdecl; external av__format; (** - * Allocate the stream private data and write the stream header to an + * Allocates the stream private data and writes the stream header to an * output media file. * * @param s media file handle @@ -1457,7 +1653,7 @@ function av_write_header(s: PAVFormatContext): cint; cdecl; external av__format; (** - * Write a packet to an output media file. + * Writes a packet to an output media file. * * The packet shall contain one audio or video frame. * The packet must be correctly interleaved according to the container @@ -1490,7 +1686,7 @@ function av_interleaved_write_frame(s: PAVFormatContext; var pkt: TAVPacket): ci cdecl; external av__format; (** - * Interleave a packet per dts in an output media file. + * Interleaves a packet per dts in an output media file. * * Packets with pkt->destruct == av_destruct_packet will be freed inside this * function, so they cannot be used after it. Note that calling av_free_packet() @@ -1527,8 +1723,8 @@ procedure ff_interleave_add_packet(s: PAVFormatContext; {$IFEND} (** - * @brief Write the stream trailer to an output media file and - * free the file private data. + * Writes the stream trailer to an output media file and frees the + * file private data. * * May only be called after a successful call to av_write_header. * @@ -1639,7 +1835,7 @@ function av_get_frame_filename(buf: PAnsiChar; buf_size: cint; {$IFEND}; (** - * Check whether filename actually is a numbered sequence generator. + * Checks whether filename actually is a numbered sequence generator. * * @param filename possible numbered sequence string * @return 1 if a valid numbered sequence string, 0 otherwise @@ -1652,7 +1848,7 @@ function av_filename_number_test(filename: PAnsiChar): cint; {$IF LIBAVFORMAT_VERSION >= 51012002} // 51.12.2 (** - * Generate an SDP for an RTP session. + * Generates an SDP for an RTP session. * * @param ac array of AVFormatContexts describing the RTP streams. If the * array is composed by only one context, such context can contain @@ -1669,6 +1865,17 @@ function avf_sdp_create(ac: PPAVFormatContext; n_files: cint; buff: PByteArray; cdecl; external av__format; {$IFEND} +{$IF LIBAVFORMAT_VERSION >= 52060000} // 52.60.0 +(** + * Returns a positive value if the given filename has one of the given + * extensions, 0 otherwise. + * + * @param extensions a comma-separated list of filename extensions + *) +function av_match_ext(filename: {const} Pchar; extensions: {const} Pchar): cint; + cdecl; external av__format; +{$IFEND} + implementation {$IF LIBAVFORMAT_VERSION < 51012002} // 51.12.2 @@ -1686,7 +1893,7 @@ begin end; {$IFEND} -{$IF LIBAVCODEC_VERSION < 52032000} // < 52.32.0 +{$IF LIBAVFORMAT_VERSION < 52032000} // < 52.32.0 procedure av_free_packet(pkt: PAVPacket); begin if ((pkt <> nil) and (@pkt^.destruct <> nil)) then diff --git a/cmake/src/lib/ffmpeg/avio.pas b/cmake/src/lib/ffmpeg/avio.pas index dc0a330b..4863ee39 100644 --- a/cmake/src/lib/ffmpeg/avio.pas +++ b/cmake/src/lib/ffmpeg/avio.pas @@ -28,11 +28,11 @@ (* * Conversion of libavformat/avio.h * unbuffered I/O operations - * revision 16100, Sat Dec 13 13:39:13 2008 UTC - * update Tue, Jun 10 01:00:00 2009 UTC - * * @warning This file has to be considered an internal but installed * header, so it should not be directly included in your projects. + * + * update to + * Max. avformat version: 52.62.0, revision 23004, Tue May 11 19:29:00 2010 CET *) unit avio; @@ -70,6 +70,16 @@ const *) AVSEEK_SIZE = $10000; +{$IF LIBAVFORMAT_VERSION >= 52056000} // 52.56.0 + (** + * Oring this flag as into the "whence" parameter to a seek function causes it to + * seek by any means (like reopening and linear reading) or other normally unreasonble + * means that can be extreemly slow. + * This may be ignored by the seek code. + *) + AVSEEK_FORCE = $20000; +{$IFEND} + type TURLInterruptCB = function (): cint; cdecl; @@ -93,7 +103,7 @@ type is_streamed: cint; (**< true if streamed (no seek possible), default = false *) max_packet_size: cint; (**< if non zero, the stream is packetized with this max packet size *) priv_data: pointer; - filename: PAnsiChar; (**< specified filename *) + filename: PAnsiChar; (**< specified URL *) end; PPURLContext = ^PURLContext; @@ -106,16 +116,54 @@ type TURLProtocol = record name: PAnsiChar; +{$IF LIBAVFORMAT_VERSION < 52047000} // 52.47.0 url_open: function (h: PURLContext; filename: {const} PAnsiChar; flags: cint): cint; cdecl; +{$ELSE} + url_open: function (h: PURLContext; url: {const} PAnsiChar; flags: cint): cint; cdecl; +{$IFEND} + +(** + * Reads up to size bytes from the resource accessed by h, and stores + * the read bytes in buf. + * + * @return The number of bytes actually read, or a negative value + * corresponding to an AVERROR code in case of error. A value of zero + * indicates that it is not possible to read more from the accessed + * resource (except if the value of the size argument is also zero). + *) url_read: function (h: PURLContext; buf: PByteArray; size: cint): cint; cdecl; - url_read_complete: function (h: PURLContext; buf: PByteArray; size: cint): cint; cdecl; + +(** + * Read as many bytes as possible (up to size), calling the + * read function multiple times if necessary. + * Will also retry if the read function returns AVERROR(EAGAIN). + * This makes special short-read handling in applications + * unnecessary, if the return value is < size then it is + * certain there was either an error or the end of file was reached. + *) url_write: function (h: PURLContext; buf: PByteArray; size: cint): cint; cdecl; + +(** + * Changes the position that will be used by the next read/write + * operation on the resource accessed by h. + * + * @param pos specifies the new position to set + * @param whence specifies how pos should be interpreted, it must be + * one of SEEK_SET (seek from the beginning), SEEK_CUR (seek from the + * current position), SEEK_END (seek from the end), or AVSEEK_SIZE + * (return the filesize of the requested resource, pos is ignored). + * @return a negative value corresponding to an AVERROR code in case + * of failure, or the resulting file position, measured in bytes from + * the beginning of the file. You can use this feature together with + * SEEK_CUR to read the current file position. + *) url_seek: function (h: PURLContext; pos: cint64; whence: cint): cint64; cdecl; + url_close: function (h: PURLContext): cint; cdecl; next: PURLProtocol; {$IF (LIBAVFORMAT_VERSION >= 52001000) and (LIBAVFORMAT_VERSION < 52004000)} // 52.1.0 .. 52.4.0 - url_read_play: function (h: PURLContext): cint; - url_read_pause: function (h: PURLContext): cint; + url_read_play: function (h: PURLContext): cint; cdecl; + url_read_pause: function (h: PURLContext): cint; cdecl; {$IFEND} {$IF LIBAVFORMAT_VERSION >= 52004000} // 52.4.0 url_read_pause: function (h: PURLContext; pause: cint): cint; cdecl; @@ -124,6 +172,9 @@ type url_read_seek: function (h: PURLContext; stream_index: cint; timestamp: cint64; flags: cint): cint64; cdecl; {$IFEND} + {$IF LIBAVFORMAT_VERSION >= 52031000} // 52.31.0 + url_get_file_handle: function (h: PURLContext): cint; cdecl; + {$IFEND} end; (** @@ -168,31 +219,85 @@ type {$IF LIBAVFORMAT_VERSION >= 52021000} // 52.21.0 +(** + * Creates an URLContext for accessing to the resource indicated by + * URL, and opens it using the URLProtocol up. + * + * @param puc pointer to the location where, in case of success, the + * function puts the pointer to the created URLContext + * @param flags flags which control how the resource indicated by URL + * is to be opened + * @return 0 in case of success, a negative value corresponding to an + * AVERROR code in case of failure + *) function url_open_protocol(puc: PPURLContext; up: PURLProtocol; +{$IF LIBAVFORMAT_VERSION < 52047000} // 52.47.0 filename: {const} PAnsiChar; flags: cint): cint; +{$ELSE} + url: {const} PAnsiChar; flags: cint): cint; +{$IFEND} cdecl; external av__format; {$IFEND} + +(** + * Creates an URLContext for accessing to the resource indicated by + * url, and opens it. + * + * @param puc pointer to the location where, in case of success, the + * function puts the pointer to the created URLContext + * @param flags flags which control how the resource indicated by url + * is to be opened + * @return 0 in case of success, a negative value corresponding to an + * AVERROR code in case of failure + *) +{$IF LIBAVFORMAT_VERSION < 52047000} // 52.47.0 function url_open(h: PPointer; filename: {const} PAnsiChar; flags: cint): cint; +{$ELSE} +function url_open(h: PPointer; url: {const} PAnsiChar; flags: cint): cint; +{$IFEND} cdecl; external av__format; function url_read (h: PURLContext; buf: PByteArray; size: cint): cint; cdecl; external av__format; +{$IF LIBAVFORMAT_VERSION >= 52034000} // 52.34.0 +function url_read_complete (h: PURLContext; buf: PByteArray; size: cint): cint; cdecl; + cdecl; external av__format; +{$IFEND} function url_write (h: PURLContext; buf: PByteArray; size: cint): cint; cdecl; external av__format; function url_seek (h: PURLContext; pos: cint64; whence: cint): cint64; cdecl; external av__format; + +(** + * Closes the resource accessed by the URLContext h, and frees the + * memory used by it. + * + * @return a negative value if an error condition occurred, 0 + * otherwise + *) function url_close (h: PURLContext): cint; cdecl; external av__format; + +(** + * Returns a non-zero value if the resource indicated by url + * exists, 0 otherwise. + *) +{$IF LIBAVFORMAT_VERSION < 52047000} // 52.47.0 function url_exist(filename: {const} PAnsiChar): cint; +{$ELSE} +function url_exist(url: {const} PAnsiChar): cint; +{$IFEND} cdecl; external av__format; + function url_filesize (h: PURLContext): cint64; cdecl; external av__format; -{ + +(** * Return the file descriptor associated with this URL. For RTP, this * will return only the RTP file descriptor, not the RTCP file descriptor. * To get both, use rtp_get_file_handles(). * * @return the file descriptor associated with this URL, or <0 on error. -} + *) (* not implemented *) function url_get_file_handle(h: PURLContext): cint; cdecl; external av__format; @@ -264,30 +369,36 @@ var url_interrupt_cb: PURLInterruptCB; external av__format; **) -{ -* If protocol is NULL, returns the first registered protocol, -* if protocol is non-NULL, returns the next registered protocol after protocol, -* or NULL if protocol is the last one. -} {$IF LIBAVFORMAT_VERSION >= 52002000} // 52.2.0 +(** + * If protocol is NULL, returns the first registered protocol, + * if protocol is non-NULL, returns the next registered protocol after protocol, + * or NULL if protocol is the last one. + *) function av_protocol_next(p: PURLProtocol): PURLProtocol; cdecl; external av__format; {$IFEND} {$IF LIBAVFORMAT_VERSION <= 52028000} // 52.28.0 (** + * Registers the URLProtocol protocol. + *) +(** * @deprecated Use av_register_protocol() instead. *) -function register_protocol (protocol: PURLProtocol): cint; +function register_protocol(protocol: PURLProtocol): cint; cdecl; external av__format; +(** Alias for register_protocol() *) +function av_register_protocol(protocol: PURLProtocol): cint; + cdecl; external av__format name 'register_protocol'; {$ELSE} -function av_register_protocol (protocol: PURLProtocol): cint; +function av_register_protocol(protocol: PURLProtocol): cint; cdecl; external av__format; {$IFEND} type - TReadWriteFunc = function (opaque: Pointer; buf: PByteArray; buf_size: cint): cint; cdecl; - TSeekFunc = function (opaque: Pointer; offset: cint64; whence: cint): cint64; cdecl; + TReadWriteFunc = function(opaque: Pointer; buf: PByteArray; buf_size: cint): cint; cdecl; + TSeekFunc = function(opaque: Pointer; offset: cint64; whence: cint): cint64; cdecl; function init_put_byte(s: PByteIOContext; buffer: PByteArray; @@ -400,11 +511,10 @@ function url_fgets(s: PByteIOContext; buf: PAnsiChar; buf_size: cint): PAnsiChar procedure put_flush_packet (s: PByteIOContext); cdecl; external av__format; - (** * Reads size bytes from ByteIOContext into buf. - * @returns number of bytes read or AVERROR + * @return number of bytes read or AVERROR *) function get_buffer(s: PByteIOContext; buf: PByteArray; size: cint): cint; cdecl; external av__format; @@ -413,7 +523,7 @@ function get_buffer(s: PByteIOContext; buf: PByteArray; size: cint): cint; * Reads size bytes from ByteIOContext into buf. * This reads at most 1 packet. If that is not enough fewer bytes will be * returned. - * @returns number of bytes read or AVERROR + * @return number of bytes read or AVERROR *) function get_partial_buffer(s: PByteIOContext; buf: PByteArray; size: cint): cint; cdecl; external av__format; @@ -449,8 +559,17 @@ function ff_get_v(bc: PByteIOContext): cuint64; function url_is_streamed(s: PByteIOContext): cint; {$IFDEF HasInline}inline;{$ENDIF} -(** @note when opened as read/write, the buffers are only used for - writing *) +(** + * Creates and initializes a ByteIOContext for accessing the + * resource referenced by the URLContext h. + * @note When the URLContext h has been opened in read+write mode, the + * ByteIOContext can be used only for writing. + * + * @param s Used to return the pointer to the created ByteIOContext. + * In case of failure the pointed to value is set to NULL. + * @return 0 in case of success, a negative value corresponding to an + * AVERROR code in case of failure + *) {$IF LIBAVFORMAT_VERSION >= 52000000} // 52.0.0 function url_fdopen (var s: PByteIOContext; h: PURLContext): cint; {$ELSE} @@ -462,6 +581,7 @@ function url_fdopen (s: PByteIOContext; h: PURLContext): cint; function url_setbufsize (s: PByteIOContext; buf_size: cint): cint; cdecl; external av__format; +{$IF LIBAVFORMAT_VERSION_MAJOR < 53} {$IF LIBAVFORMAT_VERSION >= 51015000} // 51.15.0 (** Reset the buffer for reading or writing. * @note Will drop any data currently in the buffer without transmitting it. @@ -470,14 +590,48 @@ function url_setbufsize (s: PByteIOContext; buf_size: cint): cint; function url_resetbuf(s: PByteIOContext; flags: cint): cint; cdecl; external av__format; {$IFEND} +{$IFEND} -(** @note when opened as read/write, the buffers are only used for - writing *) +{$IF LIBAVFORMAT_VERSION >= 52061000} // 52.61.0 +(** + * Rewinds the ByteIOContext using the specified buffer containing the first buf_size bytes of the file. + * Used after probing to avoid seeking. + * Joins buf and s->buffer, taking any overlap into consideration. + * @note s->buffer must overlap with buf or they can't be joined and the function fails + * @note This function is NOT part of the public API + * + * @param s The read-only ByteIOContext to rewind + * @param buf The probe buffer containing the first buf_size bytes of the file + * @param buf_size The size of buf + * @return 0 in case of success, a negative value corresponding to an + * AVERROR code in case of failure + *) +function ff_rewind_with_probe_data(s: PByteIOContext; buf: PAnsiChar; buf_size: cint): cint; + cdecl; external av__format; +{$IFEND} + +(** + * Creates and initializes a ByteIOContext for accessing the + * resource indicated by url. + * @note When the resource indicated by url has been opened in + * read+write mode, the ByteIOContext can be used only for writing. + * + * @param s Used to return the pointer to the created ByteIOContext. + * In case of failure the pointed to value is set to NULL. + * @param flags flags which control how the resource indicated by url + * is to be opened + * @return 0 in case of success, a negative value corresponding to an + * AVERROR code in case of failure + *) +{$IF LIBAVFORMAT_VERSION < 52047000} // 52.47.0 {$IF LIBAVFORMAT_VERSION >= 52000000} // 52.0.0 function url_fopen(var s: PByteIOContext; filename: {const} PAnsiChar; flags: cint): cint; {$ELSE} function url_fopen(s: PByteIOContext; filename: {const} PAnsiChar; flags: cint): cint; {$IFEND} +{$ELSE} +function url_fopen(var s: PByteIOContext; url: {const} PAnsiChar; flags: cint): cint; +{$IFEND} cdecl; external av__format; function url_fclose(s: PByteIOContext): cint; cdecl; external av__format; diff --git a/cmake/src/lib/ffmpeg/avutil.pas b/cmake/src/lib/ffmpeg/avutil.pas index 6a93ea12..c26700c6 100644 --- a/cmake/src/lib/ffmpeg/avutil.pas +++ b/cmake/src/lib/ffmpeg/avutil.pas @@ -28,22 +28,20 @@ * Conversions of * * libavutil/avutil.h: - * Min. version: 49.0.1, revision 6577, Sat Oct 7 15:30:46 2006 UTC - * Max. version: 49.14.0, revision 16912, Sun Feb 1 02:00:19 2009 UTC + * Min. version: 49.0.1, revision 6577, Sat Oct 7 15:30:46 2006 UTC + * Max. version: 50.15.2, revision 23059, Tue May 11 22:05:00 2010 CET * * libavutil/mem.h: * revision 16590, Tue Jan 13 23:44:16 2009 UTC * * libavutil/log.h: * revision 16571, Tue Jan 13 00:14:43 2009 UTC + * + * include/keep pixfmt.h (change in revision 50.01.0) + * Maybe, the pixelformats are not needed, but it has not been checked. + * log.h is only partial. + * *) -{ - Update changes auf avutil.h, mem.h and log.h - Max. version 50.03.0, Tue, Jun 09 24:00:00 2009 UTC - include/keep pixfmt.h (change in revision 50.01.0) - Maybe, the pixelformats are not needed, but it has not been checked. - log.h is only partial. -} unit avutil; @@ -65,13 +63,41 @@ uses ctypes, mathematics, rational, + {$IFDEF UNIX} + BaseUnix, + {$ENDIF} UConfig; const + (* + * IMPORTANT: The official FFmpeg C headers change very quickly. Often some + * of the data structures are changed so that they become incompatible with + * older header files. The Pascal headers have to be adjusted to those changes, + * otherwise the application might crash randomly or strange bugs (not + * necessarily related to video or audio due to buffer overflows etc.) might + * occur. + * + * In the past users reported problems with USDX that took hours to fix and + * the problem was an unsupported version of FFmpeg. So we decided to disable + * support for future versions of FFmpeg until the headers are revised by us + * for that version as they otherwise most probably will break USDX. + * + * If the headers do not yet support your FFmpeg version you may want to + * adjust the max. version numbers manually but please note: it may work but + * in many cases it does not. The USDX team does NOT PROVIDE ANY SUPPORT + * for the game if the MAX. VERSION WAS CHANGED. + * + * The only safe way to support new versions of FFmpeg is to add the changes + * of the FFmpeg git repository C headers to the Pascal headers. + * You can accelerate this process by posting a patch with the git changes + * translated to Pascal to our bug tracker (please join our IRC chat before + * you start working on it). Simply adjusting the max. versions is NOT a valid + * fix. + *) (* Max. supported version by this header *) LIBAVUTIL_MAX_VERSION_MAJOR = 50; - LIBAVUTIL_MAX_VERSION_MINOR = 3; - LIBAVUTIL_MAX_VERSION_RELEASE = 0; + LIBAVUTIL_MAX_VERSION_MINOR = 15; + LIBAVUTIL_MAX_VERSION_RELEASE = 2; LIBAVUTIL_MAX_VERSION = (LIBAVUTIL_MAX_VERSION_MAJOR * VERSION_MAJOR) + (LIBAVUTIL_MAX_VERSION_MINOR * VERSION_MINOR) + (LIBAVUTIL_MAX_VERSION_RELEASE * VERSION_RELEASE); @@ -101,6 +127,41 @@ function avutil_version(): cuint; cdecl; external av__format; {$IFEND} +{$IF LIBAVUTIL_VERSION >= 50004000} // >= 50.4.0 +(** + * Returns the libavutil build-time configuration. + *) +function avutil_configuration(): PAnsiChar; + cdecl; external av__format; + +(** + * Returns the libavutil license. + *) +function avutil_license(): PAnsiChar; + cdecl; external av__format; +{$IFEND} + +{ + TAVMediaType moved to avutil in LIBAVUTIL_VERSION 50.14.0 + but moving it in the pascal headers was not really necessary + but caused problems. So, I (KMS) left it there. + +type + TAVMediaType = ( + AVMEDIA_TYPE_UNKNOWN = -1, + AVMEDIA_TYPE_VIDEO, + AVMEDIA_TYPE_AUDIO, + AVMEDIA_TYPE_DATA, + AVMEDIA_TYPE_SUBTITLE, + AVMEDIA_TYPE_ATTACHMENT, + AVMEDIA_TYPE_NB + ); +} + +{$INCLUDE error.pas} + +(* libavutil/pixfmt.h up to revision 23144, May 16 2010 *) + type (** * Pixel format. Notes: @@ -148,8 +209,8 @@ type PIX_FMT_RGB555, ///< packed RGB 5:5:5, 16bpp, (msb)1A 5R 5G 5B(lsb), in CPU endianness, most significant bit to 0 {$IFEND} PIX_FMT_GRAY8, ///< Y , 8bpp - PIX_FMT_MONOWHITE, ///< Y , 1bpp, 0 is white, 1 is black - PIX_FMT_MONOBLACK, ///< Y , 1bpp, 0 is black, 1 is white + PIX_FMT_MONOWHITE, ///< Y , 1bpp, 0 is white, 1 is black, in each byte pixels are ordered from the msb to the lsb + PIX_FMT_MONOBLACK, ///< Y , 1bpp, 0 is black, 1 is white, in each byte pixels are ordered from the msb to the lsb PIX_FMT_PAL8, ///< 8 bit with PIX_FMT_RGB32 palette PIX_FMT_YUVJ420P, ///< planar YUV 4:2:0, 12bpp, full scale (JPEG) PIX_FMT_YUVJ422P, ///< planar YUV 4:2:2, 16bpp, full scale (JPEG) @@ -166,12 +227,12 @@ type PIX_FMT_BGR555, ///< packed RGB 5:5:5, 16bpp, (msb)1A 5B 5G 5R(lsb), in CPU endianness, most significant bit to 1 {$IFEND} PIX_FMT_BGR8, ///< packed RGB 3:3:2, 8bpp, (msb)2B 3G 3R(lsb) - PIX_FMT_BGR4, ///< packed RGB 1:2:1, 4bpp, (msb)1B 2G 1R(lsb) + PIX_FMT_BGR4, ///< packed RGB 1:2:1, bitstream, 4bpp, (msb)1B 2G 1R(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits PIX_FMT_BGR4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1B 2G 1R(lsb) PIX_FMT_RGB8, ///< packed RGB 3:3:2, 8bpp, (msb)2R 3G 3B(lsb) - PIX_FMT_RGB4, ///< packed RGB 1:2:1, 4bpp, (msb)1R 2G 1B(lsb) + PIX_FMT_RGB4, ///< packed RGB 1:2:1, bitstream, 4bpp, (msb)1R 2G 1B(lsb), a byte contains two pixels, the first pixel in the byte is the one composed by the 4 msb bits PIX_FMT_RGB4_BYTE, ///< packed RGB 1:2:1, 8bpp, (msb)1R 2G 1B(lsb) - PIX_FMT_NV12, ///< planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 for UV + PIX_FMT_NV12, ///< planar YUV 4:2:0, 12bpp, 1 plane for Y and 1 plane for the UV components, which are interleaved (first byte U and the following byte V) PIX_FMT_NV21, ///< as above, but U and V bytes are swapped {$IF LIBAVUTIL_VERSION <= 50001000} // 50.01.0 PIX_FMT_RGB32_1, ///< packed RGB 8:8:8, 32bpp, (msb)8R 8G 8B 8A(lsb), in CPU endianness @@ -193,8 +254,8 @@ type PIX_FMT_VDPAU_WMV3,///< WMV3 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers PIX_FMT_VDPAU_VC1, ///< VC-1 HW decoding with VDPAU, data[0] contains a vdpau_render_state struct which contains the bitstream of the slices as well as various fields extracted from headers {$IF LIBAVUTIL_VERSION >= 49015000} // 49.15.0 - PIX_FMT_RGB48BE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, big-endian - PIX_FMT_RGB48LE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, little-endian + PIX_FMT_RGB48BE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as big-endian + PIX_FMT_RGB48LE, ///< packed RGB 16:16:16, 48bpp, 16R, 16G, 16B, the 2-byte value for each R/G/B component is stored as little-endian {$IFEND} {$IF LIBAVUTIL_VERSION >= 50001000} // 50.01.0 PIX_FMT_RGB565BE, ///< packed RGB 5:6:5, 16bpp, (msb) 5R 6G 5B(lsb), big-endian @@ -267,11 +328,13 @@ const PIX_FMT_YUV422 = PIX_FMT_YUYV422; {$IFEND} -(* libavutil/common.h *) // until now MKTAG is all from common.h KMS 9/6/2009 +(* libavutil/common.h *) // until now MKTAG and MKBETAG is all from common.h KMS 19/5/2010 function MKTAG(a, b, c, d: AnsiChar): integer; +function MKBETAG(a, b, c, d: AnsiChar): integer; (* libavutil/mem.h *) + (* memory handling functions *) (** @@ -287,7 +350,7 @@ function av_malloc(size: cuint): pointer; (** * Allocates or reallocates a block of memory. - * If ptr is NULL and size > 0, allocates a new block. If \p + * If ptr is NULL and size > 0, allocates a new block. If * size is zero, frees the memory block pointed to by ptr. * @param size Size in bytes for the memory block to be allocated or * reallocated. @@ -326,7 +389,7 @@ function av_mallocz(size: cuint): pointer; * Duplicates the string s. * @param s string to be duplicated. * @return Pointer to a newly allocated string containing a - * copy of \p s or NULL if the string cannot be allocated. + * copy of s or NULL if the string cannot be allocated. *) function av_strdup({const} s: PAnsiChar): PAnsiChar; cdecl; external av__util; {av_malloc_attrib} @@ -388,11 +451,40 @@ const AV_LOG_DEBUG = 48; {$IFEND} +(** + * Sends the specified message to the log if the level is less than or equal + * to the current av_log_level. By default, all logging messages are sent to + * stderr. This behavior can be altered by setting a different av_vlog callback + * function. + * + * @param avcl A pointer to an arbitrary struct of which the first field is a + * pointer to an AVClass struct. + * @param level The importance level of the message, lower values signifying + * higher importance. + * @param fmt The format string (printf-compatible) that specifies how + * subsequent arguments are converted to output. + * @see av_vlog + *) + +{** to be translated if needed +#ifdef __GNUC__ +void av_log(void*, int level, const char *fmt, ...) __attribute__ ((__format__ (__printf__, 3, 4))); +#else +void av_log(void*, int level, const char *fmt, ...); +#endif + +void av_vlog(void*, int level, const char *fmt, va_list); +**} + function av_log_get_level(): cint; cdecl; external av__util; procedure av_log_set_level(level: cint); cdecl; external av__util; +{** to be translated if needed +void av_log_set_callback(void (*)(void*, int, const char*, va_list)); +void av_log_default_callback(void* ptr, int level, const char* fmt, va_list vl); +**} implementation @@ -403,4 +495,10 @@ begin Result := (ord(a) or (ord(b) shl 8) or (ord(c) shl 16) or (ord(d) shl 24)); end; +function MKBETAG(a, b, c, d: AnsiChar): integer; +begin + Result := (ord(d) or (ord(c) shl 8) or (ord(b) shl 16) or (ord(a) shl 24)); +end; + + end. diff --git a/cmake/src/lib/ffmpeg/error.pas b/cmake/src/lib/ffmpeg/error.pas new file mode 100644 index 00000000..95cecd0f --- /dev/null +++ b/cmake/src/lib/ffmpeg/error.pas @@ -0,0 +1,113 @@ +(* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * This is a part of the Pascal port of ffmpeg. + * - Changes and updates by the UltraStar Deluxe Team + * + * Conversion of libavutil/error.h + * Max. avutil version: 50.15.2, revision 23059, Tue May 11 18:30 2010 CET + * + *) + +{$IF LIBAVUTIL_VERSION >= 50012000} // >= 50.12.0 + +{* error handling *} + +const +{$IFDEF UNIX} + ENOENT = ESysENOENT; + EIO = ESysEIO; + ENOMEM = ESysENOMEM; + EINVAL = ESysEINVAL; + EDOM = ESysEDOM; + ENOSYS = ESysENOSYS; + EILSEQ = ESysEILSEQ; + EPIPE = ESysEPIPE; +{$ELSE} + ENOENT = 2; + EIO = 5; + ENOMEM = 12; + EINVAL = 22; + EPIPE = 32; // just an assumption. needs to be checked. + EDOM = 33; + {$IFDEF MSWINDOWS} + // Note: we assume that ffmpeg was compiled with MinGW. + // This must be changed if DLLs were compiled with cygwin. + ENOSYS = 40; // MSVC/MINGW: 40, CYGWIN: 88, LINUX/FPC: 38 + EILSEQ = 42; // MSVC/MINGW: 42, CYGWIN: 138, LINUX/FPC: 84 + {$ENDIF} +{$ENDIF} + +(** + * We need the sign of the error, because some platforms have + * E* and errno already negated. The previous version failed + * with Delphi, because it needed EINVAL defined. + * Warning: This code is platform dependent and assumes constants + * to be 32 bit. + * This version does the following steps: + * 1) shr 30: shifts the sign bit to bit position 2 + * 2) and $00000002: sets all other bits to zero + * positive EINVAL gives 0, negative gives 2 + * 3) not: inverts all bits. This gives -1 and -3 + * 3) - 1: positive EINVAL gives -1, negative 1 + *) +const + AVERROR_SIGN = (EINVAL shr 30) and $00000002 - 1; + +(* +#if EINVAL > 0 +#define AVERROR(e) (-(e)) {**< Returns a negative error code from a POSIX error code, to return from library functions. *} +#define AVUNERROR(e) (-(e)) {**< Returns a POSIX error code from a library function error return value. *} +#else +{* Some platforms have E* and errno already negated. *} +#define AVERROR(e) (e) +#define AVUNERROR(e) (e) +#endif +*) + +const + AVERROR_UNKNOWN = AVERROR_SIGN * EINVAL; (**< unknown error *) + AVERROR_IO = AVERROR_SIGN * EIO; (**< I/O error *) + AVERROR_NUMEXPECTED = AVERROR_SIGN * EDOM; (**< Number syntax expected in filename. *) + AVERROR_INVALIDDATA = AVERROR_SIGN * EINVAL; (**< invalid data found *) + AVERROR_NOMEM = AVERROR_SIGN * ENOMEM; (**< not enough memory *) + AVERROR_NOFMT = AVERROR_SIGN * EILSEQ; (**< unknown format *) + AVERROR_NOTSUPP = AVERROR_SIGN * ENOSYS; (**< Operation not supported. *) + AVERROR_NOENT = AVERROR_SIGN * ENOENT; (**< No such file or directory. *) +{$IF LIBAVCODEC_VERSION >= 52017000} // 52.17.0 + AVERROR_EOF = AVERROR_SIGN * EPIPE; (**< End of file. *) +{$IFEND} + // Note: function calls as constant-initializers are invalid + //AVERROR_PATCHWELCOME = -MKTAG('P','A','W','E'); {**< Not yet implemented in FFmpeg. Patches welcome. *} + AVERROR_PATCHWELCOME = -(ord('P') or (ord('A') shl 8) or (ord('W') shl 16) or (ord('E') shl 24)); +{$IFEND} + +{$IF LIBAVUTIL_VERSION >= 50013000} // >= 50.13.0 +(* + * Puts a description of the AVERROR code errnum in errbuf. + * In case of failure the global variable errno is set to indicate the + * error. Even in case of failure av_strerror() will print a generic + * error message indicating the errnum provided to errbuf. + * + * @param errbuf_size the size in bytes of errbuf + * @return 0 on success, a negative value if a description for errnum + * cannot be found + *) + +function av_strerror(errnum: cint; errbuf: Pchar; errbuf_size: cint): cint; + cdecl; external av__util; +{$IFEND} diff --git a/cmake/src/lib/ffmpeg/mathematics.pas b/cmake/src/lib/ffmpeg/mathematics.pas index 92ee0a5e..3a1f6a2c 100644 --- a/cmake/src/lib/ffmpeg/mathematics.pas +++ b/cmake/src/lib/ffmpeg/mathematics.pas @@ -26,10 +26,8 @@ (* * Conversion of libavutil/mathematics.h - * revision 16844, Wed Jan 28 08:50:10 2009 UTC + * avutil max. version 50.15.2, revision 23059, Tue May 11 22:10:00 2010 CET * - * update, MiSchi, no code change - * Fri Jun 12 2009 21:50:00 UTC *) unit mathematics; @@ -53,8 +51,18 @@ const M_E = 2.7182818284590452354; // e M_LN2 = 0.69314718055994530942; // log_e 2 M_LN10 = 2.30258509299404568402; // log_e 10 +{$IF LIBAVUTIL_VERSION >= 50009000} // >= 50.9.0 + M_LOG2_10 = 3.32192809488736234787; // log_2 10 +{$IFEND} M_PI = 3.14159265358979323846; // pi M_SQRT1_2 = 0.70710678118654752440; // 1/sqrt(2) +{$IF LIBAVUTIL_VERSION >= 50014000} // >= 50.14.0 + M_SQRT2 = 1.41421356237309504880; // sqrt(2) +{$IFEND} +{$IF LIBAVUTIL_VERSION >= 50005001} // >= 50.5.1 + NAN = 0.0/0.0; + INFINITY = 1.0/0.0; +{$IFEND} type TAVRounding = ( @@ -66,6 +74,11 @@ type ); {$IF LIBAVUTIL_VERSION >= 49013000} // 49.13.0 +(** + * Returns the greatest common divisor of a and b. + * If both a or b are 0 or either or both are <0 then behavior is + * undefined. + *) function av_gcd(a: cint64; b: cint64): cint64; cdecl; external av__util; {av_const} {$IFEND} @@ -90,6 +103,17 @@ function av_rescale_rnd (a, b, c: cint64; enum: TAVRounding): cint64; function av_rescale_q (a: cint64; bq, cq: TAVRational): cint64; cdecl; external av__util; {av_const} +{$IF LIBAVUTIL_VERSION >= 50008000} // 50.8.0 +(** + * Compares 2 timestamps each in its own timebases. + * The result of the function is undefined if one of the timestamps + * is outside the int64_t range when represented in the others timebase. + * @return -1 if ts_a is before ts_b, 1 if ts_a is after ts_b or 0 if they represent the same position + *) +function av_compare_ts(ts_a: cint64; tb_a: TAVRational; ts_b: cint64; tb_b: TAVRational): cint; + cdecl; external av__util; +{$IFEND} + implementation end. diff --git a/cmake/src/lib/ffmpeg/opt.pas b/cmake/src/lib/ffmpeg/opt.pas index a2e2cce9..c755ed35 100644 --- a/cmake/src/lib/ffmpeg/opt.pas +++ b/cmake/src/lib/ffmpeg/opt.pas @@ -23,14 +23,10 @@ * - For Mac OS X, some modifications were made by The Creative CAT, denoted as CAT * in the source codes. * - Changes and updates by the UltraStar Deluxe Team - *) - -(* + * * Conversion of libavcodec/opt.h - * revision 16912, Sun Feb 1 02:00:19 2009 UTC + * Max. avcodec version: 52.67.0, revision 23057, Tue May 11 18:17 2010 CET * - * update, MiSchi, no code change - * Fri Jun 12 2009 21:50:00 UTC *) unit opt; @@ -110,6 +106,53 @@ type unit_: {const} PAnsiChar; end; +{$IF LIBAVCODEC_VERSION >= 52042000} // >= 52.42.0 +(** + * AVOption2. + * THIS IS NOT PART OF THE API/ABI YET! + * This is identical to AVOption except that default_val was replaced by + * an union, it should be compatible with AVOption on normal platforms. + *) +type + PAVOption2 = ^TAVOption2; + TAVOption2 = record + name : {const} PAnsiChar; + + (** + * short English help text + * @todo What about other languages? + *) + help : {const} PAnsiChar; + + (** + * The offset relative to the context structure where the option + * value is stored. It should be 0 for named constants. + *) + offset : cint; + type_ : TAVOptionType; + + (** + * the default value for scalar options + *) + default_val : record + case cint of + 0 : (dbl: cdouble); + 1 : (str: PAnsiChar); + end; + min : cdouble; + max : cdouble; + flags : cint; +//FIXME think about enc-audio, ... style flags + + (** + * The logical unit to which the option belongs. Non-constant + * options and corresponding named constants share the same + * unit. May be NULL. + *) + unit_: {const} PAnsiChar; + end; +{$IFEND} + {$IF LIBAVCODEC_VERSION >= 51039000} // 51.39.0 (** * Looks for an option in obj. Looks only for the options which @@ -189,10 +232,10 @@ function av_set_q(obj: pointer; name: {const} PAnsiChar; n: TAVRational): PAVOpt function av_set_int(obj: pointer; name: {const} PAnsiChar; n: cint64): PAVOption; cdecl; external av__codec; -function av_get_double(obj: pointer; name: {const} PAnsiChar; var o_out: PAVOption): cdouble; +function av_get_double(obj: pointer; name: {const} PAnsiChar; var o_out: {const} PAVOption): cdouble; cdecl; external av__codec; -function av_get_q(obj: pointer; name: {const} PAnsiChar; var o_out: PAVOption): TAVRational; +function av_get_q(obj: pointer; name: {const} PAnsiChar; var o_out: {const} PAVOption): TAVRational; cdecl; external av__codec; function av_get_int(obj: pointer; name: {const} PAnsiChar; var o_out: {const} PAVOption): cint64; diff --git a/cmake/src/lib/ffmpeg/rational.pas b/cmake/src/lib/ffmpeg/rational.pas index b940009d..6ca9c0d1 100644 --- a/cmake/src/lib/ffmpeg/rational.pas +++ b/cmake/src/lib/ffmpeg/rational.pas @@ -27,10 +27,8 @@ (* * Conversion of libavutil/rational.h - * revision 16912, Sun Feb 1 02:00:19 2009 UTC + * avutil max. version 50.15.2, revision 23059, Tue May 11 22:10:00 2010 CET * - * update, MiSchi, no code change - * Fri Jun 12 2009 22:20:00 UTC *) unit rational; diff --git a/cmake/src/lib/ffmpeg/src/MacOSX/MacOSXReadMe.txt b/cmake/src/lib/ffmpeg/src/MacOSX/MacOSXReadMe.txt deleted file mode 100644 index c2f5826a..00000000 --- a/cmake/src/lib/ffmpeg/src/MacOSX/MacOSXReadMe.txt +++ /dev/null @@ -1,24 +0,0 @@ -If you are using fink to install ffmpeg and friends, -you can skip the rest of this notes. - -How to download an build ffmpeg for UltraStar Deluxe on Mac OS X: - -1. Open a terminal. - -2. cd into the Game/Code/lib/ffmpeg/src/MacOSX directory - -3. Run the following command: - -svn checkout svn://svn.mplayerhq.hu/ffmpeg/trunk ffmpeg - -4. The compile ffmpeg. I made a script for this: - -./build_ffmpeg.sh - -5. On OS X you have to patch the the dylibs. Run the following - script. It patches the dylibs and copies them to the - lib/ffmpeg dir: - -./copy_and_patch_dylibs.sh - -You're done. diff --git a/cmake/src/lib/ffmpeg/src/MacOSX/build_ffmpeg.sh b/cmake/src/lib/ffmpeg/src/MacOSX/build_ffmpeg.sh deleted file mode 100755 index bcb3ca1e..00000000 --- a/cmake/src/lib/ffmpeg/src/MacOSX/build_ffmpeg.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -cd ffmpeg -./configure --enable-shared --disable-static --disable-mmx -make - diff --git a/cmake/src/lib/ffmpeg/src/MacOSX/copy_and_patch_dylibs.sh b/cmake/src/lib/ffmpeg/src/MacOSX/copy_and_patch_dylibs.sh deleted file mode 100755 index 064d2ecc..00000000 --- a/cmake/src/lib/ffmpeg/src/MacOSX/copy_and_patch_dylibs.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash - -# Copy dylibs: -cp ffmpeg/libavcodec/libavcodec.51.dylib ../../libavcodec.dylib -cp ffmpeg/libavformat/libavformat.52.dylib ../../libavformat.dylib -cp ffmpeg/libavutil/libavutil.49.dylib ../../libavutil.dylib - -# Patching libavcodec: -install_name_tool -id @executable_path/libavcodec.dylib ../../libavcodec.dylib -install_name_tool -change /usr/local/lib/libavutil.dylib @executable_path/libavutil.dylib ../../libavcodec.dylib - -# Patching libavformat: -install_name_tool -id @executable_path/libavformat.dylib ../../libavformat.dylib -install_name_tool -change /usr/local/lib/libavutil.dylib @executable_path/libavutil.dylib ../../libavformat.dylib -install_name_tool -change /usr/local/lib/libavcodec.dylib @executable_path/libavcodec.dylib ../../libavformat.dylib - -# Patching libavcodec: -install_name_tool -id @executable_path/libavutil.dylib ../../libavutil.dylib - -# Printing result: -otool -L ../../libavutil.dylib -otool -L ../../libavcodec.dylib -otool -L ../../libavformat.dylib
\ No newline at end of file diff --git a/cmake/src/lib/ffmpeg/swscale.pas b/cmake/src/lib/ffmpeg/swscale.pas index c0aabf45..4f923f04 100644 --- a/cmake/src/lib/ffmpeg/swscale.pas +++ b/cmake/src/lib/ffmpeg/swscale.pas @@ -23,7 +23,7 @@ (* * Conversion of libswscale/swscale.h - * revision 27592, Fri Sep 12 21:46:53 2008 UTC + * Max. version: 0.10.0, revision 31050, Tue May 11 19:40:00 2010 CET *) unit swscale; @@ -49,10 +49,35 @@ uses UConfig; const + (* + * IMPORTANT: The official FFmpeg C headers change very quickly. Often some + * of the data structures are changed so that they become incompatible with + * older header files. The Pascal headers have to be adjusted to those changes, + * otherwise the application might crash randomly or strange bugs (not + * necessarily related to video or audio due to buffer overflows etc.) might + * occur. + * + * In the past users reported problems with USDX that took hours to fix and + * the problem was an unsupported version of FFmpeg. So we decided to disable + * support for future versions of FFmpeg until the headers are revised by us + * for that version as they otherwise most probably will break USDX. + * + * If the headers do not yet support your FFmpeg version you may want to + * adjust the max. version numbers manually but please note: it may work but + * in many cases it does not. The USDX team does NOT PROVIDE ANY SUPPORT + * for the game if the MAX. VERSION WAS CHANGED. + * + * The only safe way to support new versions of FFmpeg is to add the changes + * of the FFmpeg git repository C headers to the Pascal headers. + * You can accelerate this process by posting a patch with the git changes + * translated to Pascal to our bug tracker (please join our IRC chat before + * you start working on it). Simply adjusting the max. versions is NOT a valid + * fix. + *) (* Max. supported version by this header *) - LIBSWSCALE_MAX_VERSION_MAJOR = 0; - LIBSWSCALE_MAX_VERSION_MINOR = 7; - LIBSWSCALE_MAX_VERSION_RELEASE = 1; + LIBSWSCALE_MAX_VERSION_MAJOR = 0; + LIBSWSCALE_MAX_VERSION_MINOR = 10; + LIBSWSCALE_MAX_VERSION_RELEASE = 0; LIBSWSCALE_MAX_VERSION = (LIBSWSCALE_MAX_VERSION_MAJOR * VERSION_MAJOR) + (LIBSWSCALE_MAX_VERSION_MINOR * VERSION_MINOR) + (LIBSWSCALE_MAX_VERSION_RELEASE * VERSION_RELEASE); @@ -78,6 +103,20 @@ function swscale_version(): cuint; cdecl; external sw__scale; {$IFEND} +{$IF LIBSWSCALE_VERSION >= 000007002} // 0.7.2 +(** + * Returns the libswscale build-time configuration. + *) +function swscale_configuration(): PAnsiChar; + cdecl; external sw__scale; + +(** + * Returns the libswscale license. + *) +function swscale_license(): PAnsiChar; + cdecl; external sw__scale; +{$IFEND} + const (* values for the flags, the stuff on the command line is different *) SWS_FAST_BILINEAR = 1; @@ -124,6 +163,18 @@ const SWS_CS_SMPTE240M = 7; SWS_CS_DEFAULT = 5; +{$IF LIBSWSCALE_VERSION >= 000010000} // 0.10.0 +(** + * Returns a pointer to yuv<->rgb coefficients for the given colorspace + * suitable for sws_setColorspaceDetails(). + * + * @param colorspace One of the SWS_CS_* macros. If invalid, + * SWS_CS_DEFAULT is used. + *) + function sws_getCoefficients(colorspace: cint): Pcint; + cdecl; external sw__scale; +{$IFEND} + type // when used for filters they must have an odd number of elements @@ -148,6 +199,26 @@ type {internal structure} end; +{$IF LIBSWSCALE_VERSION >= 000008000} // 0.8.0 +(** + * Returns a positive value if pix_fmt is a supported input format, 0 + * otherwise. + *) + function sws_isSupportedInput(pix_fmt: TAVPixelFormat): cint; + cdecl; external sw__scale; + +(** + * Returns a positive value if pix_fmt is a supported output format, 0 + * otherwise. + *) + function sws_isSupportedOutput(pix_fmt: TAVPixelFormat): cint; + cdecl; external sw__scale; +{$IFEND} + +(** + * Frees the swscaler context swsContext. + * If swsContext is NULL, then does nothing. + *) procedure sws_freeContext(swsContext: PSwsContext); cdecl; external sw__scale; @@ -175,6 +246,10 @@ function sws_getContext(srcW: cint; srcH: cint; srcFormat: TAVPixelFormat; * slice in the image in dst. A slice is a sequence of consecutive * rows in an image. * + * Slices have to be provided in sequential order, either in + * top-bottom or bottom-top order. If slices are provided in + * non-sequential order the behavior of the function is undefined. + * * @param context the scaling context previously created with * sws_getContext() * @param srcSlice the array containing the pointers to the planes of @@ -192,14 +267,15 @@ function sws_getContext(srcW: cint; srcH: cint; srcFormat: TAVPixelFormat; * the destination image * @return the height of the output slice *) -function sws_scale(context: PSwsContext; srcSlice: PPCuint8Array; srcStride: PCintArray; - srcSliceY: cint; srcSliceH: cint; dst: PPCuint8Array; dstStride: PCintArray): cint; +function sws_scale(context: PSwsContext; {const} srcSlice: PPCuint8Array; {const} srcStride: PCintArray; + srcSliceY: cint; srcSliceH: cint; {const} dst: PPCuint8Array; {const} dstStride: PCintArray): cint; cdecl; external sw__scale; {$IF LIBSWSCALE_VERSION_MAJOR < 1} // deprecated. Use sws_scale() instead. -function sws_scale_ordered(context: PSwsContext; src: PPCuint8Array; srcStride: PCintArray; - srcSliceY: cint; srcSliceH: cint; dst: PPCuint8Array; dstStride: PCintArray): cint; +function sws_scale_ordered(context: PSwsContext; {const} src: PPCuint8Array; + srcStride: PCintArray; srcSliceY: cint; srcSliceH: cint; + dst: PPCuint8Array; dstStride: PCintArray): cint; cdecl; external sw__scale; deprecated; {$IFEND} diff --git a/cmake/src/lib/fft/UFFT.pas b/cmake/src/lib/fft/UFFT.pas index 6b094c98..5a056a8c 100644 --- a/cmake/src/lib/fft/UFFT.pas +++ b/cmake/src/lib/fft/UFFT.pas @@ -47,7 +47,7 @@ unit UFFT; {$IFDEF FPC} {$MODE Delphi} - {$H+} // Use AnsiString + {$H+} // Use long strings {$ENDIF} interface diff --git a/cmake/src/lib/freetype/demo/engine-test.bdsproj b/cmake/src/lib/freetype/demo/engine-test.bdsproj index 9547f18f..e5b3e97d 100644 --- a/cmake/src/lib/freetype/demo/engine-test.bdsproj +++ b/cmake/src/lib/freetype/demo/engine-test.bdsproj @@ -27,13 +27,13 @@ <Compiler Name="I">1</Compiler>
<Compiler Name="J">0</Compiler>
<Compiler Name="K">0</Compiler>
- <Compiler Name="L">1</Compiler>
- <Compiler Name="M">0</Compiler>
- <Compiler Name="N">1</Compiler>
- <Compiler Name="O">0</Compiler>
- <Compiler Name="P">1</Compiler>
- <Compiler Name="Q">0</Compiler>
- <Compiler Name="R">0</Compiler>
+ <Compiler Name="L">1</Compiler> + <Compiler Name="M">0</Compiler> + <Compiler Name="N">1</Compiler> + <Compiler Name="O">1</Compiler> + <Compiler Name="P">1</Compiler> + <Compiler Name="Q">0</Compiler> + <Compiler Name="R">0</Compiler> <Compiler Name="S">0</Compiler>
<Compiler Name="T">0</Compiler>
<Compiler Name="U">0</Compiler>
diff --git a/cmake/src/lib/freetype/demo/engine-test.dpr b/cmake/src/lib/freetype/demo/engine-test.dpr index 80177735..bbd7d890 100644 --- a/cmake/src/lib/freetype/demo/engine-test.dpr +++ b/cmake/src/lib/freetype/demo/engine-test.dpr @@ -27,7 +27,9 @@ uses ctypes in '../../ctypes/ctypes.pas', {$ENDIF} FreeType in '../freetype.pas', - UFont in '../../../base/UFont.pas', + UFont in 'UFont.pas', + //UFont in '../../../base/UFont.pas', + UUnicodeUtils in '../../../base/UUnicodeUtils.pas', math, sysutils; @@ -41,7 +43,7 @@ const //FONT_FILE = 'C:/Windows/Fonts/Arial.ttf'; //FONT_FILE = 'C:/Windows/Fonts/SimSun.ttf'; //FONT_FILE = 'eurostarregularextended.ttf'; - FONT_FILE = 'FreeSans.ttf'; + FONT_FILE = '../../../../game/fonts/FreeSans/FreeSans.ttf'; var OurFont: TScalableFont; @@ -129,11 +131,11 @@ begin // Really Nice Perspective Calculations glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); - //OurFont := TFTScalableFont.Create(FONT_FILE, 64); + OurFont := TFTScalableFont.Create(FONT_FILE, 64, 0.03); //OurFont := TFTFont.Create(FONT_FILE, 128); - OurFont := TFTScalableOutlineFont.Create(FONT_FILE, 64, 0.05); + //OurFont := TFTScalableOutlineFont.Create(FONT_FILE, 64, 0.03); //OurFont.UseKerning := false; - TFTScalableOutlineFont(OurFont).SetOutlineColor(1, 0, 0); + //TFTScalableOutlineFont(OurFont).SetOutlineColor(1, 0, 0, 1); //OurFont := TOutlineFont.Create(FONT_FILE, 32, 2); //OurFont.LineSpacing := OurFont.LineSpacing * 0.5; @@ -183,7 +185,7 @@ begin //OurFont.SetOutlineColor(0.5, 0.5, 0.5); //OurFont.ReflectionSpacing := -4; //OurFont.UseKerning := false; - OurFont.Height := 64;//cnt2; + OurFont.Height := 150;//cnt2; //OurFont.Reset; //OurFont.Aspect := 2; @@ -191,7 +193,7 @@ begin bounds := OurFont.BBox(msg); //glRectf(bounds.Left, OurFont.Ascender, bounds.Right, OurFont.Ascender-OurFont.Height); - glColor3f(1, 1, 1); + glColor4f(1, 1, 1, 1); //OurFont.ReflectionSpacing := 0; OurFont.Print(msg); diff --git a/cmake/src/lib/freetype/demo/engine-test.lpi b/cmake/src/lib/freetype/demo/engine-test.lpi index 6cbfe1eb..45483a56 100644 --- a/cmake/src/lib/freetype/demo/engine-test.lpi +++ b/cmake/src/lib/freetype/demo/engine-test.lpi @@ -28,14 +28,14 @@ </local>
</RunParams>
<Units Count="16">
- <Unit0>
- <Filename Value="engine-test.dpr"/>
- <IsPartOfProject Value="True"/>
- <CursorPos X="25" Y="135"/>
- <TopLine Value="118"/>
- <EditorIndex Value="0"/>
- <UsageCount Value="72"/>
- <Loaded Value="True"/>
+ <Unit0> + <Filename Value="engine-test.dpr"/> + <IsPartOfProject Value="True"/> + <CursorPos X="18" Y="25"/> + <TopLine Value="1"/> + <EditorIndex Value="0"/> + <UsageCount Value="72"/> + <Loaded Value="True"/> </Unit0>
<Unit1>
<Filename Value="JEDI-SDL\OpenGL\Pas\opengl12.pas"/>
@@ -139,13 +139,22 @@ <UnitName Value="UFont"/>
<CursorPos X="15" Y="1752"/>
<TopLine Value="1734"/>
- <UsageCount Value="10"/>
- </Unit15>
- </Units>
- <JumpHistory Count="0" HistoryIndex="-1"/>
- </ProjectOptions>
- <CompilerOptions>
- <Version Value="8"/>
+ <UsageCount Value="10"/> + </Unit15> + </Units> + <JumpHistory Count="2" HistoryIndex="1"> + <Position1> + <Filename Value="engine-test.dpr"/> + <Caret Line="52" Column="10" TopLine="37"/> + </Position1> + <Position2> + <Filename Value="engine-test.dpr"/> + <Caret Line="1" Column="1" TopLine="1"/> + </Position2> + </JumpHistory> + </ProjectOptions> + <CompilerOptions> + <Version Value="8"/> <PathDelim Value="\"/>
<SearchPaths>
<IncludeFiles Value="..\..\JEDI-SDL\SDL\Pas\"/>
diff --git a/cmake/src/lib/freetype/freetype.pas b/cmake/src/lib/freetype/freetype.pas index 6a9d2062..01f507bc 100644 --- a/cmake/src/lib/freetype/freetype.pas +++ b/cmake/src/lib/freetype/freetype.pas @@ -1,23 +1,42 @@ -//---------------------------------------------------------------------------- -// FreeType2 pascal header -//---------------------------------------------------------------------------- -// Anti-Grain Geometry - Version 2.4 (Public License) -// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) -// -// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3) -// Pascal Port By: Milan Marusinec alias Milano -// milan@marusinec.sk -// http://www.aggpas.org -// Copyright (c) 2005-2007 -// -// Permission to copy, use, modify, sell and distribute this software -// is granted provided this copyright notice appears in all copies. -// This software is provided "as is" without express or implied -// warranty, and with no claim as to its suitability for any purpose. -// -//---------------------------------------------------------------------------- -// Adapted by the UltraStar Deluxe Team -//---------------------------------------------------------------------------- +(***************************************************************************) +(* *) +(* freetype.h *) +(* *) +(* FreeType high-level API and common types (specification only). *) +(* *) +(* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by *) +(* David Turner, Robert Wilhelm, and Werner Lemberg. *) +(* *) +(* This file is part of the FreeType project, and may only be used, *) +(* modified, and distributed under the terms of the FreeType project *) +(* license, LICENSE.TXT. By continuing to use, modify, or distribute *) +(* this file you indicate that you have read the license and *) +(* understand and accept it fully. *) +(* *) +(***************************************************************************) + +(***************************************************************************) +(* Initial Pascal port by *) +(***************************************************************************) +(* Anti-Grain Geometry - Version 2.4 (Public License) *) +(* Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) *) +(* *) +(* Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3) *) +(* Pascal Port By: Milan Marusinec alias Milano *) +(* milan@marusinec.sk *) +(* http://www.aggpas.org *) +(* Copyright (c) 2005-2007 *) +(* *) +(* Permission to copy, use, modify, sell and distribute this software *) +(* is granted provided this copyright notice appears in all copies. *) +(* This software is provided "as is" without express or implied *) +(* warranty, and with no claim as to its suitability for any purpose. *) +(* *) +(***************************************************************************) + +(***************************************************************************) +(* Extended by the UltraStar Deluxe Team *) +(***************************************************************************) unit freetype; @@ -36,7 +55,7 @@ uses const {$IF Defined(MSWINDOWS)} - ft_lib = 'libfreetype-6.dll'; + ft_lib = 'freetype6.dll'; {$ELSEIF Defined(DARWIN)} ft_lib = 'libfreetype.dylib'; {$LINKLIB libfreetype} @@ -45,32 +64,24 @@ const {$IFEND} type - FT_Byte = cuchar; - FT_Short = csshort; - FT_UShort = cushort; - FT_Int = csint; - FT_UInt = cuint; - FT_Int16 = cint16; - FT_UInt16 = cuint16; - FT_Int32 = cint32; - FT_UInt32 = cuint32; - FT_Long = cslong; - FT_ULong = culong; - - FT_Fixed = cslong; - FT_Pos = cslong; - FT_Error = cint; - FT_F26Dot6 = cslong; - FT_String = cchar; - FT_Bool = cuchar; - - PFT_Byte = ^FT_Byte; - PFT_Short = ^FT_Short; - PFT_String = ^FT_String; - - - TByteArray = array [0 .. (MaxInt div SizeOf(byte))-1] of byte; - PByteArray = ^TByteArray; + (*************************************************************************) + (* *) + (* <Type> *) + (* FT_Library *) + (* *) + (* <Description> *) + (* A handle to a FreeType library instance. Each `library' is *) + (* completely independent from the others; it is the `root' of a set *) + (* of objects like fonts, faces, sizes, etc. *) + (* *) + (* It also embeds a memory manager (see @FT_Memory), as well as a *) + (* scan-line converter object (see @FT_Raster). *) + (* *) + (* <Note> *) + (* Library objects are normally created by @FT_Init_FreeType, and *) + (* destroyed with @FT_Done_FreeType. *) + (* *) + FT_Library = Pointer; (*************************************************************************) @@ -141,6 +152,34 @@ const (*************************************************************************) (* *) + (* <Macro> *) + (* FT_ENC_TAG *) + (* *) + (* <Description> *) + (* This macro converts four-letter tags into an unsigned long. It is *) + (* used to define `encoding' identifiers (see @FT_Encoding). *) + (* *) + (* <Note> *) + (* Since many 16-bit compilers don't like 32-bit enumerations, you *) + (* should redefine this macro in case of problems to something like *) + (* this: *) + (* *) + (* { *) + (* #define FT_ENC_TAG( value, a, b, c, d ) value *) + (* } *) + (* *) + (* to get a simple enumeration without assigning special numbers. *) + (* *) + { + #define FT_ENC_TAG( value, a, b, c, d ) \ + value = ( ( (FT_UInt32)(a) << 24 ) | \ + ( (FT_UInt32)(b) << 16 ) | \ + ( (FT_UInt32)(c) << 8 ) | \ + (FT_UInt32)(d) ) + } + + (*************************************************************************) + (* *) (* <Enum> *) (* FT_Encoding *) (* *) @@ -278,65 +317,47 @@ const (* *) type PFT_Encoding = ^FT_Encoding; - FT_Encoding = array[0..3] of char; -const - FT_ENCODING_NONE: FT_Encoding = (#0 ,#0 ,#0 ,#0 ); - FT_ENCODING_MS_SYMBOL: FT_Encoding = ('s', 'y', 'm', 'b' ); - FT_ENCODING_UNICODE: FT_Encoding = ('u', 'n', 'i', 'c' ); - - FT_ENCODING_SJIS: FT_Encoding = ('s', 'j', 'i', 's'); - FT_ENCODING_GB2312: FT_Encoding = ('g', 'b', ' ', ' '); - FT_ENCODING_BIG5: FT_Encoding = ('b', 'i', 'g', '5'); - FT_ENCODING_WANSUNG: FT_Encoding = ('w', 'a', 'n', 's'); - FT_ENCODING_JOHAB: FT_Encoding = ('j', 'o', 'h', 'a'); - - (*************************************************************************) - (* *) - (* <Enum> *) - (* FT_Glyph_Format *) - (* *) - (* <Description> *) - (* An enumeration type used to describe the format of a given glyph *) - (* image. Note that this version of FreeType only supports two image *) - (* formats, even though future font drivers will be able to register *) - (* their own format. *) - (* *) - (* <Values> *) - (* FT_GLYPH_FORMAT_NONE :: *) - (* The value 0 is reserved and does describe a glyph format. *) - (* *) - (* FT_GLYPH_FORMAT_COMPOSITE :: *) - (* The glyph image is a composite of several other images. This *) - (* format is _only_ used with @FT_LOAD_NO_RECURSE, and is used to *) - (* report compound glyphs (like accented characters). *) - (* *) - (* FT_GLYPH_FORMAT_BITMAP :: *) - (* The glyph image is a bitmap, and can be described as an *) - (* @FT_Bitmap. You generally need to access the `bitmap' field of *) - (* the @FT_GlyphSlotRec structure to read it. *) - (* *) - (* FT_GLYPH_FORMAT_OUTLINE :: *) - (* The glyph image is a vertorial outline made of line segments *) - (* and Bezier arcs; it can be described as an @FT_Outline; you *) - (* generally want to access the `outline' field of the *) - (* @FT_GlyphSlotRec structure to read it. *) - (* *) - (* FT_GLYPH_FORMAT_PLOTTER :: *) - (* The glyph image is a vectorial path with no inside/outside *) - (* contours. Some Type 1 fonts, like those in the Hershey family, *) - (* contain glyphs in this format. These are described as *) - (* @FT_Outline, but FreeType isn't currently capable of rendering *) - (* them correctly. *) - (* *) -type - FT_Glyph_Format = array[0..3] of char; + FT_Encoding = cint32; // 32 bit enum of FT_ENC_TAG const - FT_GLYPH_FORMAT_NONE: FT_Glyph_Format = (#0, #0, #0, #0 ); - - FT_GLYPH_FORMAT_COMPOSITE: FT_Glyph_Format = ('c', 'o', 'm', 'p' ); - FT_GLYPH_FORMAT_BITMAP: FT_Glyph_Format = ('b', 'i', 't', 's' ); - FT_GLYPH_FORMAT_OUTLINE: FT_Glyph_Format = ('o', 'u', 't', 'l' ); - FT_GLYPH_FORMAT_PLOTTER: FT_Glyph_Format = ('p', 'l', 'o', 't' ); + FT_ENCODING_NONE = (Ord(#0) shl 24) or + (Ord(#0) shl 16) or + (Ord(#0) shl 8) or + (Ord(#0) shl 0); + + FT_ENCODING_MS_SYMBOL = (Ord('s') shl 24) or + (Ord('y') shl 16) or + (Ord('m') shl 8) or + (Ord('b') shl 0); + + FT_ENCODING_UNICODE = (Ord('u') shl 24) or + (Ord('n') shl 16) or + (Ord('i') shl 8) or + (Ord('c') shl 0); + + FT_ENCODING_SJIS = (Ord('s') shl 24) or + (Ord('j') shl 16) or + (Ord('i') shl 8) or + (Ord('s') shl 0); + + FT_ENCODING_GB2312 = (Ord('g') shl 24) or + (Ord('b') shl 16) or + (Ord(' ') shl 8) or + (Ord(' ') shl 0); + + FT_ENCODING_BIG5 = (Ord('b') shl 24) or + (Ord('i') shl 16) or + (Ord('g') shl 8) or + (Ord('5') shl 0); + + FT_ENCODING_WANSUNG = (Ord('w') shl 24) or + (Ord('a') shl 16) or + (Ord('n') shl 8) or + (Ord('s') shl 0); + + FT_ENCODING_JOHAB = (Ord('j') shl 24) or + (Ord('o') shl 16) or + (Ord('h') shl 8) or + (Ord('a') shl 0); (*************************************************************************) @@ -358,7 +379,7 @@ const const FT_STYLE_FLAG_ITALIC = 1 shl 0; FT_STYLE_FLAG_BOLD = 1 shl 1; - + (*************************************************************************** * @@ -567,7 +588,7 @@ const (* perform this pass. *) (* *) type - FT_Render_Mode = FT_Int; + FT_Render_Mode = cint; const FT_RENDER_MODE_NORMAL = 0; FT_RENDER_MODE_LIGHT = FT_RENDER_MODE_NORMAL + 1; @@ -579,63 +600,34 @@ const (*************************************************************************) (* *) - (* <Enum> *) - (* FT_Pixel_Mode *) + (* <Type> *) + (* FT_GlyphSlot *) (* *) (* <Description> *) - (* An enumeration type used to describe the format of pixels in a *) - (* given bitmap. Note that additional formats may be added in the *) - (* future. *) + (* A handle to a given `glyph slot'. A slot is a container where it *) + (* is possible to load any one of the glyphs contained in its parent *) + (* face. *) (* *) - (* <Values> *) - (* FT_PIXEL_MODE_NONE :: *) - (* Value 0 is reserved. *) - (* *) - (* FT_PIXEL_MODE_MONO :: *) - (* A monochrome bitmap, using 1 bit per pixel. Note that pixels *) - (* are stored in most-significant order (MSB), which means that *) - (* the left-most pixel in a byte has value 128. *) - (* *) - (* FT_PIXEL_MODE_GRAY :: *) - (* An 8-bit bitmap, generally used to represent anti-aliased glyph *) - (* images. Each pixel is stored in one byte. Note that the number *) - (* of value `gray' levels is stored in the `num_bytes' field of *) - (* the @FT_Bitmap structure (it generally is 256). *) - (* *) - (* FT_PIXEL_MODE_GRAY2 :: *) - (* A 2-bit/pixel bitmap, used to represent embedded anti-aliased *) - (* bitmaps in font files according to the OpenType specification. *) - (* We haven't found a single font using this format, however. *) - (* *) - (* FT_PIXEL_MODE_GRAY4 :: *) - (* A 4-bit/pixel bitmap, used to represent embedded anti-aliased *) - (* bitmaps in font files according to the OpenType specification. *) - (* We haven't found a single font using this format, however. *) - (* *) - (* FT_PIXEL_MODE_LCD :: *) - (* An 8-bit bitmap, used to represent RGB or BGR decimated glyph *) - (* images used for display on LCD displays; the bitmap is three *) - (* times wider than the original glyph image. See also *) - (* @FT_RENDER_MODE_LCD. *) - (* *) - (* FT_PIXEL_MODE_LCD_V :: *) - (* An 8-bit bitmap, used to represent RGB or BGR decimated glyph *) - (* images used for display on rotated LCD displays; the bitmap *) - (* is three times taller than the original glyph image. See also *) - (* @FT_RENDER_MODE_LCD_V. *) + (* In other words, each time you call @FT_Load_Glyph or *) + (* @FT_Load_Char, the slot's content is erased by the new glyph data, *) + (* i.e. the glyph's metrics, its image (bitmap or outline), and *) + (* other control information. *) + (* *) + (* <Also> *) + (* @FT_GlyphSlotRec details the publicly accessible glyph fields. *) (* *) type - FT_Pixel_Mode = byte; -const - FT_PIXEL_MODE_NONE = 0; - FT_PIXEL_MODE_MONO = FT_PIXEL_MODE_NONE + 1; - FT_PIXEL_MODE_GRAY = FT_PIXEL_MODE_MONO + 1; - FT_PIXEL_MODE_GRAY2 = FT_PIXEL_MODE_GRAY + 1; - FT_PIXEL_MODE_GRAY4 = FT_PIXEL_MODE_GRAY2 + 1; - FT_PIXEL_MODE_LCD = FT_PIXEL_MODE_GRAY4 + 1; - FT_PIXEL_MODE_LCD_V = FT_PIXEL_MODE_LCD + 1; + FT_GlyphSlot = ^FT_GlyphSlotRec; - FT_PIXEL_MODE_MAX = FT_PIXEL_MODE_LCD_V + 1; (* do not remove *) + +{$DEFINE TYPE_DECL} +{$I ftconfig.inc} +{$I fttypes.inc} +{$I ftimage.inc} +{$I ftglyph.inc} +{$I ftstroke.inc} +{$I ftoutln.inc} +{$UNDEF TYPE_DECL} (*************************************************************************) @@ -674,7 +666,6 @@ const (* vertAdvance :: *) (* Advance height for vertical layout. *) (* *) -type FT_Glyph_Metrics = record width , height : FT_Pos; @@ -759,140 +750,6 @@ type (*************************************************************************) (* *) - (* <Struct> *) - (* FT_Vector *) - (* *) - (* <Description> *) - (* A simple structure used to store a 2D vector; coordinates are of *) - (* the FT_Pos type. *) - (* *) - (* <Fields> *) - (* x :: The horizontal coordinate. *) - (* y :: The vertical coordinate. *) - (* *) - PFT_Vector = ^FT_Vector; - FT_Vector = record - x , - y : FT_Pos; - end; - - - (*************************************************************************) - (* *) - (* <Struct> *) - (* FT_Outline *) - (* *) - (* <Description> *) - (* This structure is used to describe an outline to the scan-line *) - (* converter. *) - (* *) - (* <Fields> *) - (* n_contours :: The number of contours in the outline. *) - (* *) - (* n_points :: The number of points in the outline. *) - (* *) - (* points :: A pointer to an array of `n_points' FT_Vector *) - (* elements, giving the outline's point coordinates. *) - (* *) - (* tags :: A pointer to an array of `n_points' chars, giving *) - (* each outline point's type. If bit 0 is unset, the *) - (* point is `off' the curve, i.e. a Bezier control *) - (* point, while it is `on' when set. *) - (* *) - (* Bit 1 is meaningful for `off' points only. If set, *) - (* it indicates a third-order Bezier arc control point; *) - (* and a second-order control point if unset. *) - (* *) - (* contours :: An array of `n_contours' shorts, giving the end *) - (* point of each contour within the outline. For *) - (* example, the first contour is defined by the points *) - (* `0' to `contours[0]', the second one is defined by *) - (* the points `contours[0]+1' to `contours[1]', etc. *) - (* *) - (* flags :: A set of bit flags used to characterize the outline *) - (* and give hints to the scan-converter and hinter on *) - (* how to convert/grid-fit it. See FT_Outline_Flags. *) - (* *) - PFT_Outline = ^FT_Outline; - FT_Outline = record - n_contours : FT_Short; - n_points : FT_Short; - - points : PFT_Vector; - tags : PChar; - contours : PFT_Short; - - flags : FT_Int; - end; - - - (*************************************************************************) - (* *) - (* <Struct> *) - (* FT_Bitmap *) - (* *) - (* <Description> *) - (* A structure used to describe a bitmap or pixmap to the raster. *) - (* Note that we now manage pixmaps of various depths through the *) - (* `pixel_mode' field. *) - (* *) - (* <Fields> *) - (* rows :: The number of bitmap rows. *) - (* *) - (* width :: The number of pixels in bitmap row. *) - (* *) - (* pitch :: The pitch's absolute value is the number of bytes *) - (* taken by one bitmap row, including padding. *) - (* However, the pitch is positive when the bitmap has *) - (* a `down' flow, and negative when it has an `up' *) - (* flow. In all cases, the pitch is an offset to add *) - (* to a bitmap pointer in order to go down one row. *) - (* *) - (* buffer :: A typeless pointer to the bitmap buffer. This *) - (* value should be aligned on 32-bit boundaries in *) - (* most cases. *) - (* *) - (* num_grays :: This field is only used with *) - (* `FT_PIXEL_MODE_GRAY'; it gives the number of gray *) - (* levels used in the bitmap. *) - (* *) - (* pixel_mode :: The pixel mode, i.e., how pixel bits are stored. *) - (* See @FT_Pixel_Mode for possible values. *) - (* *) - (* palette_mode :: This field is only used with paletted pixel modes; *) - (* it indicates how the palette is stored. *) - (* *) - (* palette :: A typeless pointer to the bitmap palette; only *) - (* used for paletted pixel modes. *) - (* *) - (* <Note> *) - (* For now, the only pixel mode supported by FreeType are mono and *) - (* grays. However, drivers might be added in the future to support *) - (* more `colorful' options. *) - (* *) - (* When using pixel modes pal2, pal4 and pal8 with a void `palette' *) - (* field, a gray pixmap with respectively 4, 16, and 256 levels of *) - (* gray is assumed. This, in order to be compatible with some *) - (* embedded bitmap formats defined in the TrueType specification. *) - (* *) - (* Note that no font was found presenting such embedded bitmaps, so *) - (* this is currently completely unhandled by the library. *) - (* *) - PFT_Bitmap = ^FT_Bitmap; - FT_Bitmap = record - rows , - width : FT_Int; - pitch : FT_Int; - buffer : PByteArray; - num_grays : FT_Short; - pixel_mode , - palette_mode : byte; - palette : pointer; - end; - - - (*************************************************************************) - (* *) (* <Type> *) (* FT_Face *) (* *) @@ -950,183 +807,10 @@ type PAFT_CharMap = ^FT_CharMap; AFT_CharMap = array[0..High(Word)] of FT_CharMap; - (*************************************************************************) - (* *) - (* <Type> *) - (* FT_Library *) - (* *) - (* <Description> *) - (* A handle to a FreeType library instance. Each `library' is *) - (* completely independent from the others; it is the `root' of a set *) - (* of objects like fonts, faces, sizes, etc. *) - (* *) - (* It also embeds a memory manager (see @FT_Memory), as well as a *) - (* scan-line converter object (see @FT_Raster). *) - (* *) - (* <Note> *) - (* Library objects are normally created by @FT_Init_FreeType, and *) - (* destroyed with @FT_Done_FreeType. *) - (* *) - FT_Library = ^FT_LibraryRec; - FT_LibraryRec = record // internal - end; - - (*************************************************************************) - (* *) - (* <Section> *) - (* glyph_management *) - (* *) - (* <Title> *) - (* Glyph Management *) - (* *) - (* <Abstract> *) - (* Generic interface to manage individual glyph data. *) - (* *) - (* <Description> *) - (* This section contains definitions used to manage glyph data *) - (* through generic FT_Glyph objects. Each of them can contain a *) - (* bitmap, a vector outline, or even images in other formats. *) - (* *) - (*************************************************************************) - - (* forward declaration to a private type *) - PFT_Glyph_Class = ^FT_Glyph_Class; - FT_Glyph_Class = record // internal - end; - - (*************************************************************************) - (* *) - (* <Type> *) - (* FT_Glyph *) - (* *) - (* <Description> *) - (* Handle to an object used to model generic glyph images. It is a *) - (* pointer to the @FT_GlyphRec structure and can contain a glyph *) - (* bitmap or pointer. *) - (* *) - (* <Note> *) - (* Glyph objects are not owned by the library. You must thus release *) - (* them manually (through @FT_Done_Glyph) _before_ calling *) - (* @FT_Done_FreeType. *) - (* *) - FT_Glyph = ^FT_GlyphRec; - - (*************************************************************************) - (* *) - (* <Struct> *) - (* FT_GlyphRec *) - (* *) - (* <Description> *) - (* The root glyph structure contains a given glyph image plus its *) - (* advance width in 16.16 fixed float format. *) - (* *) - (* <Fields> *) - (* library :: A handle to the FreeType library object. *) - (* *) - (* clazz :: A pointer to the glyph's class. Private. *) - (* *) - (* format :: The format of the glyph's image. *) - (* *) - (* advance :: A 16.16 vector that gives the glyph's advance width. *) - (* *) - FT_GlyphRec = record - library_: FT_Library; - clazz: PFT_Glyph_Class; - format: FT_Glyph_Format; - advance: FT_Vector; - end; - - - (*************************************************************************) - (* *) - (* <Type> *) - (* FT_BitmapGlyph *) - (* *) - (* <Description> *) - (* A handle to an object used to model a bitmap glyph image. This is *) - (* a sub-class of @FT_Glyph, and a pointer to @FT_BitmapGlyphRec. *) - (* *) - FT_BitmapGlyph = ^FT_BitmapGlyphRec; - (*************************************************************************) - (* *) - (* <Struct> *) - (* FT_BitmapGlyphRec *) - (* *) - (* <Description> *) - (* A structure used for bitmap glyph images. This really is a *) - (* `sub-class' of `FT_GlyphRec'. *) - (* *) - (* <Fields> *) - (* root :: The root FT_Glyph fields. *) - (* *) - (* left :: The left-side bearing, i.e., the horizontal distance *) - (* from the current pen position to the left border of the *) - (* glyph bitmap. *) - (* *) - (* top :: The top-side bearing, i.e., the vertical distance from *) - (* the current pen position to the top border of the glyph *) - (* bitmap. This distance is positive for upwards-y! *) - (* *) - (* bitmap :: A descriptor for the bitmap. *) - (* *) - (* <Note> *) - (* You can typecast FT_Glyph to FT_BitmapGlyph if you have *) - (* glyph->format == FT_GLYPH_FORMAT_BITMAP. This lets you access *) - (* the bitmap's contents easily. *) - (* *) - (* The corresponding pixel buffer is always owned by the BitmapGlyph *) - (* and is thus created and destroyed with it. *) - (* *) - FT_BitmapGlyphRec = record - root: FT_GlyphRec; - left: FT_Int; - top: FT_Int; - bitmap: FT_Bitmap; - end; - (*************************************************************************) - (* *) - (* <Type> *) - (* FT_OutlineGlyph *) - (* *) - (* <Description> *) - (* A handle to an object used to model an outline glyph image. This *) - (* is a sub-class of @FT_Glyph, and a pointer to @FT_OutlineGlyphRec. *) - (* *) - FT_OutlineGlyph = ^FT_OutlineGlyphRec; - (*************************************************************************) - (* *) - (* <Struct> *) - (* FT_OutlineGlyphRec *) - (* *) - (* <Description> *) - (* A structure used for outline (vectorial) glyph images. This *) - (* really is a `sub-class' of `FT_GlyphRec'. *) - (* *) - (* <Fields> *) - (* root :: The root FT_Glyph fields. *) - (* *) - (* outline :: A descriptor for the outline. *) - (* *) - (* <Note> *) - (* You can typecast FT_Glyph to FT_OutlineGlyph if you have *) - (* glyph->format == FT_GLYPH_FORMAT_OUTLINE. This lets you access *) - (* the outline's content easily. *) - (* *) - (* As the outline is extracted from a glyph slot, its coordinates are *) - (* expressed normally in 26.6 pixels, unless the flag *) - (* FT_LOAD_NO_SCALE was used in FT_Load_Glyph() or FT_Load_Char(). *) - (* *) - (* The outline's tables are always owned by the object and are *) - (* destroyed with it. *) - (* *) - FT_OutlineGlyphRec = record - root: FT_GlyphRec; - outline: FT_Outline; - end; (*************************************************************************) @@ -1149,101 +833,6 @@ type (*************************************************************************) (* *) - (* <FuncType> *) - (* FT_Generic_Finalizer *) - (* *) - (* <Description> *) - (* Describes a function used to destroy the `client' data of any *) - (* FreeType object. See the description of the FT_Generic type for *) - (* details of usage. *) - (* *) - (* <Input> *) - (* The address of the FreeType object which is under finalization. *) - (* Its client data is accessed through its `generic' field. *) - (* *) - FT_Generic_Finalizer = procedure(AnObject : pointer ); cdecl; - - (*************************************************************************) - (* *) - (* <Struct> *) - (* FT_Generic *) - (* *) - (* <Description> *) - (* Client applications often need to associate their own data to a *) - (* variety of FreeType core objects. For example, a text layout API *) - (* might want to associate a glyph cache to a given size object. *) - (* *) - (* Most FreeType object contains a `generic' field, of type *) - (* FT_Generic, which usage is left to client applications and font *) - (* servers. *) - (* *) - (* It can be used to store a pointer to client-specific data, as well *) - (* as the address of a `finalizer' function, which will be called by *) - (* FreeType when the object is destroyed (for example, the previous *) - (* client example would put the address of the glyph cache destructor *) - (* in the `finalizer' field). *) - (* *) - (* <Fields> *) - (* data :: A typeless pointer to any client-specified data. This *) - (* field is completely ignored by the FreeType library. *) - (* *) - (* finalizer :: A pointer to a `generic finalizer' function, which *) - (* will be called when the object is destroyed. If this *) - (* field is set to NULL, no code will be called. *) - (* *) - FT_Generic = record - data : pointer; - finalizer : FT_Generic_Finalizer; - end; - - (*************************************************************************) - (* *) - (* <Struct> *) - (* FT_BBox *) - (* *) - (* <Description> *) - (* A structure used to hold an outline's bounding box, i.e., the *) - (* coordinates of its extrema in the horizontal and vertical *) - (* directions. *) - (* *) - (* <Fields> *) - (* xMin :: The horizontal minimum (left-most). *) - (* *) - (* yMin :: The vertical minimum (bottom-most). *) - (* *) - (* xMax :: The horizontal maximum (right-most). *) - (* *) - (* yMax :: The vertical maximum (top-most). *) - (* *) - PFT_BBox = ^FT_BBox; - FT_BBox = record - xMin, yMin : FT_Pos; - xMax, yMax : FT_Pos; - end; - - - (*************************************************************************) - (* *) - (* <Type> *) - (* FT_GlyphSlot *) - (* *) - (* <Description> *) - (* A handle to a given `glyph slot'. A slot is a container where it *) - (* is possible to load any one of the glyphs contained in its parent *) - (* face. *) - (* *) - (* In other words, each time you call @FT_Load_Glyph or *) - (* @FT_Load_Char, the slot's content is erased by the new glyph data, *) - (* i.e. the glyph's metrics, its image (bitmap or outline), and *) - (* other control information. *) - (* *) - (* <Also> *) - (* @FT_GlyphSlotRec details the publicly accessible glyph fields. *) - (* *) - FT_GlyphSlot = ^FT_GlyphSlotRec; - - (*************************************************************************) - (* *) (* <Struct> *) (* FT_GlyphSlotRec *) (* *) @@ -1432,7 +1021,7 @@ type subglyphs : FT_SubGlyph; control_data : pointer; - control_len : longint; + control_len : clong; lsb_delta: FT_Pos; rsb_delta: FT_Pos; @@ -1497,15 +1086,15 @@ type (* computations. *) (* *) FT_Size_Metrics = record - x_ppem , - y_ppem : FT_UShort; - x_scale , - y_scale : FT_Fixed; - - ascender , - descender : FT_Pos; - height : FT_Pos; - max_advance : FT_Pos; + x_ppem, (* horizontal pixels per EM *) + y_ppem: FT_UShort; (* vertical pixels per EM *) + x_scale, (* scaling values used to convert font *) + y_scale: FT_Fixed; (* units to 26.6 fractional pixels *) + + ascender, (* ascender in 26.6 frac. pixels *) + descender: FT_Pos; (* descender in 26.6 frac. pixels *) + height: FT_Pos; (* text height in 26.6 frac. pixels *) + max_advance: FT_Pos; (* max horizontal advance, in 26.6 pixels *) end; (*************************************************************************) @@ -1786,21 +1375,29 @@ type encoding_id : FT_UShort; end; + +{$I ftconfig.inc} +{$I fttypes.inc} +{$I ftimage.inc} +{$I ftglyph.inc} +{$I ftstroke.inc} +{$I ftoutln.inc} + + { GLOBAL PROCEDURES } (*************************************************************************) (* *) (* @macro: *) - (* FT_CURVE_TAG ( flag ) *) + (* FT_HAS_KERNING( face ) *) (* *) - function FT_CURVE_TAG(flag: byte): byte; - -const - FT_CURVE_TAG_ON = 1; - FT_CURVE_TAG_CONIC = 0; - FT_CURVE_TAG_CUBIC = 2; - + (* @description: *) + (* A macro that returns true whenever a face object contains kerning *) + (* data that can be accessed with @FT_Get_Kerning. *) + (* *) + function FT_HAS_KERNING(face : FT_Face ) : cbool; + (*************************************************************************) (* *) (* @macro: *) @@ -1813,16 +1410,6 @@ const (* *) function FT_IS_SCALABLE(face : FT_Face ) : cbool; - (*************************************************************************) - (* *) - (* @macro: *) - (* FT_HAS_KERNING( face ) *) - (* *) - (* @description: *) - (* A macro that returns true whenever a face object contains kerning *) - (* data that can be accessed with @FT_Get_Kerning. *) - (* *) - function FT_HAS_KERNING(face : FT_Face ) : cbool; (*************************************************************************) (* *) @@ -2284,216 +1871,12 @@ const pixel_height : FT_UInt ) : FT_Error; cdecl; external ft_lib name 'FT_Set_Pixel_Sizes'; - (*************************************************************************) - (* *) - (* <Function> *) - (* FT_Get_Glyph *) - (* *) - (* <Description> *) - (* A function used to extract a glyph image from a slot. *) - (* *) - (* <Input> *) - (* slot :: A handle to the source glyph slot. *) - (* *) - (* <Output> *) - (* aglyph :: A handle to the glyph object. *) - (* *) - (* <Return> *) - (* FreeType error code. 0 means success. *) - (* *) - function FT_Get_Glyph( - slot: FT_GlyphSlot; - out aglyph: FT_Glyph ): FT_Error; - cdecl; external ft_lib name 'FT_Get_Glyph'; - - (*************************************************************************) - (* *) - (* <Enum> *) - (* FT_Glyph_BBox_Mode *) - (* *) - (* <Description> *) - (* The mode how the values of @FT_Glyph_Get_CBox are returned. *) - (* *) - (* <Values> *) - (* FT_GLYPH_BBOX_UNSCALED :: *) - (* Return unscaled font units. *) - (* *) - (* FT_GLYPH_BBOX_SUBPIXELS :: *) - (* Return unfitted 26.6 coordinates. *) - (* *) - (* FT_GLYPH_BBOX_GRIDFIT :: *) - (* Return grid-fitted 26.6 coordinates. *) - (* *) - (* FT_GLYPH_BBOX_TRUNCATE :: *) - (* Return coordinates in integer pixels. *) - (* *) - (* FT_GLYPH_BBOX_PIXELS :: *) - (* Return grid-fitted pixel coordinates. *) - (* *) -type - FT_Glyph_BBox_Mode = FT_UInt; const - FT_GLYPH_BBOX_UNSCALED = 0; - FT_GLYPH_BBOX_SUBPIXELS = 0; - FT_GLYPH_BBOX_GRIDFIT = 1; - FT_GLYPH_BBOX_TRUNCATE = 2; - FT_GLYPH_BBOX_PIXELS = 3; - - (*************************************************************************) - (* *) - (* <Function> *) - (* FT_Glyph_Get_CBox *) - (* *) - (* <Description> *) - (* Return a glyph's `control box'. The control box encloses all the *) - (* outline's points, including Bézier control points. Though it *) - (* coincides with the exact bounding box for most glyphs, it can be *) - (* slightly larger in some situations (like when rotating an outline *) - (* which contains Bézier outside arcs). *) - (* *) - (* Computing the control box is very fast, while getting the bounding *) - (* box can take much more time as it needs to walk over all segments *) - (* and arcs in the outline. To get the latter, you can use the *) - (* `ftbbox' component which is dedicated to this single task. *) - (* *) - (* <Input> *) - (* glyph :: A handle to the source glyph object. *) - (* *) - (* mode :: The mode which indicates how to interpret the returned *) - (* bounding box values. *) - (* *) - (* <Output> *) - (* acbox :: The glyph coordinate bounding box. Coordinates are *) - (* expressed in 1/64th of pixels if it is grid-fitted. *) - (* *) - (* <Note> *) - (* Coordinates are relative to the glyph origin, using the Y-upwards *) - (* convention. *) - (* *) - (* If the glyph has been loaded with @FT_LOAD_NO_SCALE, `bbox_mode' *) - (* must be set to @FT_GLYPH_BBOX_UNSCALED to get unscaled font *) - (* units in 26.6 pixel format. The value @FT_GLYPH_BBOX_SUBPIXELS *) - (* is another name for this constant. *) - (* *) - (* Note that the maximum coordinates are exclusive, which means that *) - (* one can compute the width and height of the glyph image (be it in *) - (* integer or 26.6 pixels) as: *) - (* *) - (* { *) - (* width = bbox.xMax - bbox.xMin; *) - (* height = bbox.yMax - bbox.yMin; *) - (* } *) - (* *) - (* Note also that for 26.6 coordinates, if `bbox_mode' is set to *) - (* @FT_GLYPH_BBOX_GRIDFIT, the coordinates will also be grid-fitted, *) - (* which corresponds to: *) - (* *) - (* { *) - (* bbox.xMin = FLOOR(bbox.xMin); *) - (* bbox.yMin = FLOOR(bbox.yMin); *) - (* bbox.xMax = CEILING(bbox.xMax); *) - (* bbox.yMax = CEILING(bbox.yMax); *) - (* } *) - (* *) - (* To get the bbox in pixel coordinates, set `bbox_mode' to *) - (* @FT_GLYPH_BBOX_TRUNCATE. *) - (* *) - (* To get the bbox in grid-fitted pixel coordinates, set `bbox_mode' *) - (* to @FT_GLYPH_BBOX_PIXELS. *) - (* *) - procedure FT_Glyph_Get_CBox( glyph: FT_Glyph; - bbox_mode: FT_UInt; - out acbox: FT_BBox ); - cdecl; external ft_lib name 'FT_Glyph_Get_CBox'; - - (*************************************************************************) - (* *) - (* <Function> *) - (* FT_Glyph_To_Bitmap *) - (* *) - (* <Description> *) - (* Converts a given glyph object to a bitmap glyph object. *) - (* *) - (* <InOut> *) - (* the_glyph :: A pointer to a handle to the target glyph. *) - (* *) - (* <Input> *) - (* render_mode :: An enumeration that describe how the data is *) - (* rendered. *) - (* *) - (* origin :: A pointer to a vector used to translate the glyph *) - (* image before rendering. Can be 0 (if no *) - (* translation). The origin is expressed in *) - (* 26.6 pixels. *) - (* *) - (* destroy :: A boolean that indicates that the original glyph *) - (* image should be destroyed by this function. It is *) - (* never destroyed in case of error. *) - (* *) - (* <Return> *) - (* FreeType error code. 0 means success. *) - (* *) - (* <Note> *) - (* The glyph image is translated with the `origin' vector before *) - (* rendering. *) - (* *) - (* The first parameter is a pointer to a FT_Glyph handle, that will *) - (* be replaced by this function. Typically, you would use (omitting *) - (* error handling): *) - (* *) - (* *) - (* { *) - (* FT_Glyph glyph; *) - (* FT_BitmapGlyph glyph_bitmap; *) - (* *) - (* *) - (* // load glyph *) - (* error = FT_Load_Char( face, glyph_index, FT_LOAD_DEFAUT ); *) - (* *) - (* // extract glyph image *) - (* error = FT_Get_Glyph( face->glyph, &glyph ); *) - (* *) - (* // convert to a bitmap (default render mode + destroy old) *) - (* if ( glyph->format != FT_GLYPH_FORMAT_BITMAP ) *) - (* { *) - (* error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_DEFAULT, *) - (* 0, 1 ); *) - (* if ( error ) // glyph unchanged *) - (* ... *) - (* } *) - (* *) - (* // access bitmap content by typecasting *) - (* glyph_bitmap = (FT_BitmapGlyph)glyph; *) - (* *) - (* // do funny stuff with it, like blitting/drawing *) - (* ... *) - (* *) - (* // discard glyph image (bitmap or not) *) - (* FT_Done_Glyph( glyph ); *) - (* } *) - (* *) - (* *) - (* This function does nothing if the glyph format isn't scalable. *) - (* *) - function FT_Glyph_To_Bitmap(var the_glyph: FT_Glyph; - render_mode: FT_Render_Mode; - origin: PFT_Vector; - destroy: FT_Bool ): FT_Error; - cdecl; external ft_lib name 'FT_Glyph_To_Bitmap'; + FT_ANGLE_PI = 180 shl 16; + FT_ANGLE_2PI = FT_ANGLE_PI * 2; + FT_ANGLE_PI2 = FT_ANGLE_PI div 2; + FT_ANGLE_PI4 = FT_ANGLE_PI div 4; - (*************************************************************************) - (* *) - (* <Function> *) - (* FT_Done_Glyph *) - (* *) - (* <Description> *) - (* Destroys a given glyph. *) - (* *) - (* <Input> *) - (* glyph :: A handle to the target glyph object. *) - (* *) - procedure FT_Done_Glyph( glyph: FT_Glyph ); - cdecl; external ft_lib name 'FT_Done_Glyph'; implementation @@ -2504,17 +1887,17 @@ begin result := flag and 3; end; -{ FT_IS_SCALABLE } -function FT_IS_SCALABLE(face : FT_Face ) : cbool; -begin - result := cbool(face.face_flags and FT_FACE_FLAG_SCALABLE ); -end; - { FT_HAS_KERNING } function FT_HAS_KERNING(face : FT_Face ) : cbool; begin result := cbool(face.face_flags and FT_FACE_FLAG_KERNING ); end; +{ FT_IS_SCALABLE } +function FT_IS_SCALABLE(face : FT_Face ) : cbool; +begin + result := cbool(face.face_flags and FT_FACE_FLAG_SCALABLE ); +end; + end. diff --git a/cmake/src/lib/freetype/ftconfig.inc b/cmake/src/lib/freetype/ftconfig.inc new file mode 100644 index 00000000..100fb2e0 --- /dev/null +++ b/cmake/src/lib/freetype/ftconfig.inc @@ -0,0 +1,35 @@ +(***************************************************************************) +(* *) +(* ftconfig.h *) +(* *) +(* ANSI-specific configuration file (specification only). *) +(* *) +(* Copyright 1996-2001, 2002, 2003, 2004, 2006, 2007 by *) +(* David Turner, Robert Wilhelm, and Werner Lemberg. *) +(* *) +(* This file is part of the FreeType project, and may only be used, *) +(* modified, and distributed under the terms of the FreeType project *) +(* license, LICENSE.TXT. By continuing to use, modify, or distribute *) +(* this file you indicate that you have read the license and *) +(* understand and accept it fully. *) +(* *) +(***************************************************************************) +(***************************************************************************) +(* Pascal port by the UltraStar Deluxe Team *) +(***************************************************************************) + +{$IFDEF TYPE_DECL} + + (*************************************************************************) + (* *) + (* IntN types *) + (* *) + (* Used to guarantee the size of some specific integers. *) + (* *) + FT_Int16 = cint16; + FT_UInt16 = cuint16; + FT_Int32 = cint32; + FT_UInt32 = cuint32; + +{$ENDIF TYPE_DECL} + diff --git a/cmake/src/lib/freetype/ftglyph.inc b/cmake/src/lib/freetype/ftglyph.inc new file mode 100644 index 00000000..0d4acc99 --- /dev/null +++ b/cmake/src/lib/freetype/ftglyph.inc @@ -0,0 +1,435 @@ +(***************************************************************************) +(* *) +(* ftglyph.h *) +(* *) +(* FreeType convenience functions to handle glyphs (specification). *) +(* *) +(* Copyright 1996-2001, 2002, 2003, 2006 by *) +(* David Turner, Robert Wilhelm, and Werner Lemberg. *) +(* *) +(* This file is part of the FreeType project, and may only be used, *) +(* modified, and distributed under the terms of the FreeType project *) +(* license, LICENSE.TXT. By continuing to use, modify, or distribute *) +(* this file you indicate that you have read the license and *) +(* understand and accept it fully. *) +(* *) +(***************************************************************************) +(***************************************************************************) +(* Pascal port by the UltraStar Deluxe Team *) +(***************************************************************************) + + + (*************************************************************************) + (* *) + (* This file contains the definition of several convenience functions *) + (* that can be used by client applications to easily retrieve glyph *) + (* bitmaps and outlines from a given face. *) + (* *) + (* These functions should be optional if you are writing a font server *) + (* or text layout engine on top of FreeType. However, they are pretty *) + (* handy for many other simple uses of the library. *) + (* *) + (*************************************************************************) + + (*************************************************************************) + (* *) + (* <Section> *) + (* glyph_management *) + (* *) + (* <Title> *) + (* Glyph Management *) + (* *) + (* <Abstract> *) + (* Generic interface to manage individual glyph data. *) + (* *) + (* <Description> *) + (* This section contains definitions used to manage glyph data *) + (* through generic FT_Glyph objects. Each of them can contain a *) + (* bitmap, a vector outline, or even images in other formats. *) + (* *) + (*************************************************************************) + +{$IFDEF TYPE_DECL} + + (* forward declaration to a private type *) + PFT_Glyph_Class = Pointer; + + + (*************************************************************************) + (* *) + (* <Type> *) + (* FT_Glyph *) + (* *) + (* <Description> *) + (* Handle to an object used to model generic glyph images. It is a *) + (* pointer to the @FT_GlyphRec structure and can contain a glyph *) + (* bitmap or pointer. *) + (* *) + (* <Note> *) + (* Glyph objects are not owned by the library. You must thus release *) + (* them manually (through @FT_Done_Glyph) _before_ calling *) + (* @FT_Done_FreeType. *) + (* *) + FT_Glyph = ^FT_GlyphRec; + + (*************************************************************************) + (* *) + (* <Struct> *) + (* FT_GlyphRec *) + (* *) + (* <Description> *) + (* The root glyph structure contains a given glyph image plus its *) + (* advance width in 16.16 fixed float format. *) + (* *) + (* <Fields> *) + (* library :: A handle to the FreeType library object. *) + (* *) + (* clazz :: A pointer to the glyph's class. Private. *) + (* *) + (* format :: The format of the glyph's image. *) + (* *) + (* advance :: A 16.16 vector that gives the glyph's advance width. *) + (* *) + FT_GlyphRec = record + library_: FT_Library; + clazz: PFT_Glyph_Class; + format: FT_Glyph_Format; + advance: FT_Vector; + end; + + + (*************************************************************************) + (* *) + (* <Type> *) + (* FT_BitmapGlyph *) + (* *) + (* <Description> *) + (* A handle to an object used to model a bitmap glyph image. This is *) + (* a sub-class of @FT_Glyph, and a pointer to @FT_BitmapGlyphRec. *) + (* *) + FT_BitmapGlyph = ^FT_BitmapGlyphRec; + + (*************************************************************************) + (* *) + (* <Struct> *) + (* FT_BitmapGlyphRec *) + (* *) + (* <Description> *) + (* A structure used for bitmap glyph images. This really is a *) + (* `sub-class' of `FT_GlyphRec'. *) + (* *) + (* <Fields> *) + (* root :: The root FT_Glyph fields. *) + (* *) + (* left :: The left-side bearing, i.e., the horizontal distance *) + (* from the current pen position to the left border of the *) + (* glyph bitmap. *) + (* *) + (* top :: The top-side bearing, i.e., the vertical distance from *) + (* the current pen position to the top border of the glyph *) + (* bitmap. This distance is positive for upwards-y! *) + (* *) + (* bitmap :: A descriptor for the bitmap. *) + (* *) + (* <Note> *) + (* You can typecast FT_Glyph to FT_BitmapGlyph if you have *) + (* glyph->format == FT_GLYPH_FORMAT_BITMAP. This lets you access *) + (* the bitmap's contents easily. *) + (* *) + (* The corresponding pixel buffer is always owned by the BitmapGlyph *) + (* and is thus created and destroyed with it. *) + (* *) + FT_BitmapGlyphRec = record + root: FT_GlyphRec; + left: FT_Int; + top: FT_Int; + bitmap: FT_Bitmap; + end; + + + (*************************************************************************) + (* *) + (* <Type> *) + (* FT_OutlineGlyph *) + (* *) + (* <Description> *) + (* A handle to an object used to model an outline glyph image. This *) + (* is a sub-class of @FT_Glyph, and a pointer to @FT_OutlineGlyphRec. *) + (* *) + FT_OutlineGlyph = ^FT_OutlineGlyphRec; + + + (*************************************************************************) + (* *) + (* <Struct> *) + (* FT_OutlineGlyphRec *) + (* *) + (* <Description> *) + (* A structure used for outline (vectorial) glyph images. This *) + (* really is a `sub-class' of `FT_GlyphRec'. *) + (* *) + (* <Fields> *) + (* root :: The root FT_Glyph fields. *) + (* *) + (* outline :: A descriptor for the outline. *) + (* *) + (* <Note> *) + (* You can typecast FT_Glyph to FT_OutlineGlyph if you have *) + (* glyph->format == FT_GLYPH_FORMAT_OUTLINE. This lets you access *) + (* the outline's content easily. *) + (* *) + (* As the outline is extracted from a glyph slot, its coordinates are *) + (* expressed normally in 26.6 pixels, unless the flag *) + (* FT_LOAD_NO_SCALE was used in FT_Load_Glyph() or FT_Load_Char(). *) + (* *) + (* The outline's tables are always owned by the object and are *) + (* destroyed with it. *) + (* *) + FT_OutlineGlyphRec = record + root: FT_GlyphRec; + outline: FT_Outline; + end; + +{$ELSE TYPE_DECL} + + (*************************************************************************) + (* *) + (* <Function> *) + (* FT_Get_Glyph *) + (* *) + (* <Description> *) + (* A function used to extract a glyph image from a slot. *) + (* *) + (* <Input> *) + (* slot :: A handle to the source glyph slot. *) + (* *) + (* <Output> *) + (* aglyph :: A handle to the glyph object. *) + (* *) + (* <Return> *) + (* FreeType error code. 0 means success. *) + (* *) + function FT_Get_Glyph( + slot: FT_GlyphSlot; + out aglyph: FT_Glyph ): FT_Error; + cdecl; external ft_lib name 'FT_Get_Glyph'; + + (*************************************************************************) + (* *) + (* <Function> *) + (* FT_Glyph_Copy *) + (* *) + (* <Description> *) + (* A function used to copy a glyph image. Note that the created *) + (* @FT_Glyph object must be released with @FT_Done_Glyph. *) + (* *) + (* <Input> *) + (* source :: A handle to the source glyph object. *) + (* *) + (* <Output> *) + (* target :: A handle to the target glyph object. 0~in case of *) + (* error. *) + (* *) + (* <Return> *) + (* FreeType error code. 0~means success. *) + (* *) + function FT_Glyph_Copy(source: FT_Glyph; + var target: FT_Glyph ): FT_Error; + cdecl; external ft_lib name 'FT_Glyph_Copy'; + +{$ENDIF TYPE_DECL} +{$IFDEF TYPE_DECL} + + (*************************************************************************) + (* *) + (* <Enum> *) + (* FT_Glyph_BBox_Mode *) + (* *) + (* <Description> *) + (* The mode how the values of @FT_Glyph_Get_CBox are returned. *) + (* *) + (* <Values> *) + (* FT_GLYPH_BBOX_UNSCALED :: *) + (* Return unscaled font units. *) + (* *) + (* FT_GLYPH_BBOX_SUBPIXELS :: *) + (* Return unfitted 26.6 coordinates. *) + (* *) + (* FT_GLYPH_BBOX_GRIDFIT :: *) + (* Return grid-fitted 26.6 coordinates. *) + (* *) + (* FT_GLYPH_BBOX_TRUNCATE :: *) + (* Return coordinates in integer pixels. *) + (* *) + (* FT_GLYPH_BBOX_PIXELS :: *) + (* Return grid-fitted pixel coordinates. *) + (* *) + FT_Glyph_BBox_Mode = cint; +{$ELSE TYPE_DECL} +const + FT_GLYPH_BBOX_UNSCALED = 0; + FT_GLYPH_BBOX_SUBPIXELS = 0; + FT_GLYPH_BBOX_GRIDFIT = 1; + FT_GLYPH_BBOX_TRUNCATE = 2; + FT_GLYPH_BBOX_PIXELS = 3; + + + (*************************************************************************) + (* *) + (* <Function> *) + (* FT_Glyph_Get_CBox *) + (* *) + (* <Description> *) + (* Return a glyph's `control box'. The control box encloses all the *) + (* outline's points, including Bézier control points. Though it *) + (* coincides with the exact bounding box for most glyphs, it can be *) + (* slightly larger in some situations (like when rotating an outline *) + (* which contains Bézier outside arcs). *) + (* *) + (* Computing the control box is very fast, while getting the bounding *) + (* box can take much more time as it needs to walk over all segments *) + (* and arcs in the outline. To get the latter, you can use the *) + (* `ftbbox' component which is dedicated to this single task. *) + (* *) + (* <Input> *) + (* glyph :: A handle to the source glyph object. *) + (* *) + (* mode :: The mode which indicates how to interpret the returned *) + (* bounding box values. *) + (* *) + (* <Output> *) + (* acbox :: The glyph coordinate bounding box. Coordinates are *) + (* expressed in 1/64th of pixels if it is grid-fitted. *) + (* *) + (* <Note> *) + (* Coordinates are relative to the glyph origin, using the Y-upwards *) + (* convention. *) + (* *) + (* If the glyph has been loaded with @FT_LOAD_NO_SCALE, `bbox_mode' *) + (* must be set to @FT_GLYPH_BBOX_UNSCALED to get unscaled font *) + (* units in 26.6 pixel format. The value @FT_GLYPH_BBOX_SUBPIXELS *) + (* is another name for this constant. *) + (* *) + (* Note that the maximum coordinates are exclusive, which means that *) + (* one can compute the width and height of the glyph image (be it in *) + (* integer or 26.6 pixels) as: *) + (* *) + (* { *) + (* width = bbox.xMax - bbox.xMin; *) + (* height = bbox.yMax - bbox.yMin; *) + (* } *) + (* *) + (* Note also that for 26.6 coordinates, if `bbox_mode' is set to *) + (* @FT_GLYPH_BBOX_GRIDFIT, the coordinates will also be grid-fitted, *) + (* which corresponds to: *) + (* *) + (* { *) + (* bbox.xMin = FLOOR(bbox.xMin); *) + (* bbox.yMin = FLOOR(bbox.yMin); *) + (* bbox.xMax = CEILING(bbox.xMax); *) + (* bbox.yMax = CEILING(bbox.yMax); *) + (* } *) + (* *) + (* To get the bbox in pixel coordinates, set `bbox_mode' to *) + (* @FT_GLYPH_BBOX_TRUNCATE. *) + (* *) + (* To get the bbox in grid-fitted pixel coordinates, set `bbox_mode' *) + (* to @FT_GLYPH_BBOX_PIXELS. *) + (* *) + procedure FT_Glyph_Get_CBox( glyph: FT_Glyph; + bbox_mode: FT_UInt; + out acbox: FT_BBox ); + cdecl; external ft_lib name 'FT_Glyph_Get_CBox'; + + + (*************************************************************************) + (* *) + (* <Function> *) + (* FT_Glyph_To_Bitmap *) + (* *) + (* <Description> *) + (* Converts a given glyph object to a bitmap glyph object. *) + (* *) + (* <InOut> *) + (* the_glyph :: A pointer to a handle to the target glyph. *) + (* *) + (* <Input> *) + (* render_mode :: An enumeration that describe how the data is *) + (* rendered. *) + (* *) + (* origin :: A pointer to a vector used to translate the glyph *) + (* image before rendering. Can be 0 (if no *) + (* translation). The origin is expressed in *) + (* 26.6 pixels. *) + (* *) + (* destroy :: A boolean that indicates that the original glyph *) + (* image should be destroyed by this function. It is *) + (* never destroyed in case of error. *) + (* *) + (* <Return> *) + (* FreeType error code. 0 means success. *) + (* *) + (* <Note> *) + (* The glyph image is translated with the `origin' vector before *) + (* rendering. *) + (* *) + (* The first parameter is a pointer to a FT_Glyph handle, that will *) + (* be replaced by this function. Typically, you would use (omitting *) + (* error handling): *) + (* *) + (* *) + (* { *) + (* FT_Glyph glyph; *) + (* FT_BitmapGlyph glyph_bitmap; *) + (* *) + (* *) + (* // load glyph *) + (* error = FT_Load_Char( face, glyph_index, FT_LOAD_DEFAUT ); *) + (* *) + (* // extract glyph image *) + (* error = FT_Get_Glyph( face->glyph, &glyph ); *) + (* *) + (* // convert to a bitmap (default render mode + destroy old) *) + (* if ( glyph->format != FT_GLYPH_FORMAT_BITMAP ) *) + (* { *) + (* error = FT_Glyph_To_Bitmap( &glyph, FT_RENDER_MODE_DEFAULT, *) + (* 0, 1 ); *) + (* if ( error ) // glyph unchanged *) + (* ... *) + (* } *) + (* *) + (* // access bitmap content by typecasting *) + (* glyph_bitmap = (FT_BitmapGlyph)glyph; *) + (* *) + (* // do funny stuff with it, like blitting/drawing *) + (* ... *) + (* *) + (* // discard glyph image (bitmap or not) *) + (* FT_Done_Glyph( glyph ); *) + (* } *) + (* *) + (* *) + (* This function does nothing if the glyph format isn't scalable. *) + (* *) + function FT_Glyph_To_Bitmap(var the_glyph: FT_Glyph; + render_mode: FT_Render_Mode; + origin: PFT_Vector; + destroy: FT_Bool ): FT_Error; + cdecl; external ft_lib name 'FT_Glyph_To_Bitmap'; + + + (*************************************************************************) + (* *) + (* <Function> *) + (* FT_Done_Glyph *) + (* *) + (* <Description> *) + (* Destroys a given glyph. *) + (* *) + (* <Input> *) + (* glyph :: A handle to the target glyph object. *) + (* *) + procedure FT_Done_Glyph( glyph: FT_Glyph ); + cdecl; external ft_lib name 'FT_Done_Glyph'; + +{$ENDIF TYPE_DECL} diff --git a/cmake/src/lib/freetype/ftimage.inc b/cmake/src/lib/freetype/ftimage.inc new file mode 100644 index 00000000..d16d52a2 --- /dev/null +++ b/cmake/src/lib/freetype/ftimage.inc @@ -0,0 +1,849 @@ +(***************************************************************************) +(* *) +(* ftimage.h *) +(* *) +(* FreeType glyph image formats and default raster interface *) +(* (specification). *) +(* *) +(* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by *) +(* David Turner, Robert Wilhelm, and Werner Lemberg. *) +(* *) +(* This file is part of the FreeType project, and may only be used, *) +(* modified, and distributed under the terms of the FreeType project *) +(* license, LICENSE.TXT. By continuing to use, modify, or distribute *) +(* this file you indicate that you have read the license and *) +(* understand and accept it fully. *) +(* *) +(***************************************************************************) +(***************************************************************************) +(* Pascal port by the UltraStar Deluxe Team *) +(***************************************************************************) + + (*************************************************************************) + (* *) + (* Note: A `raster' is simply a scan-line converter, used to render *) + (* FT_Outlines into FT_Bitmaps. *) + (* *) + (*************************************************************************) + +{$IFDEF TYPE_DECL} + + (*************************************************************************) + (* *) + (* <Type> *) + (* FT_Pos *) + (* *) + (* <Description> *) + (* The type FT_Pos is a 32-bit integer used to store vectorial *) + (* coordinates. Depending on the context, these can represent *) + (* distances in integer font units, or 16,16, or 26.6 fixed float *) + (* pixel coordinates. *) + (* *) + FT_Pos = cslong; + + + (*************************************************************************) + (* *) + (* <Struct> *) + (* FT_Vector *) + (* *) + (* <Description> *) + (* A simple structure used to store a 2D vector; coordinates are of *) + (* the FT_Pos type. *) + (* *) + (* <Fields> *) + (* x :: The horizontal coordinate. *) + (* y :: The vertical coordinate. *) + (* *) + PFT_Vector = ^FT_Vector; + FT_Vector = record + x , + y : FT_Pos; + end; + + PFT_VectorArray = ^FT_VectorArray; + FT_VectorArray = array[0 .. (MaxInt div SizeOf(FT_Vector))-1] of FT_Vector; + + (*************************************************************************) + (* *) + (* <Struct> *) + (* FT_BBox *) + (* *) + (* <Description> *) + (* A structure used to hold an outline's bounding box, i.e., the *) + (* coordinates of its extrema in the horizontal and vertical *) + (* directions. *) + (* *) + (* <Fields> *) + (* xMin :: The horizontal minimum (left-most). *) + (* *) + (* yMin :: The vertical minimum (bottom-most). *) + (* *) + (* xMax :: The horizontal maximum (right-most). *) + (* *) + (* yMax :: The vertical maximum (top-most). *) + (* *) + PFT_BBox = ^FT_BBox; + FT_BBox = record + xMin, yMin : FT_Pos; + xMax, yMax : FT_Pos; + end; + + + (*************************************************************************) + (* *) + (* <Enum> *) + (* FT_Pixel_Mode *) + (* *) + (* <Description> *) + (* An enumeration type used to describe the format of pixels in a *) + (* given bitmap. Note that additional formats may be added in the *) + (* future. *) + (* *) + (* <Values> *) + (* FT_PIXEL_MODE_NONE :: *) + (* Value 0 is reserved. *) + (* *) + (* FT_PIXEL_MODE_MONO :: *) + (* A monochrome bitmap, using 1 bit per pixel. Note that pixels *) + (* are stored in most-significant order (MSB), which means that *) + (* the left-most pixel in a byte has value 128. *) + (* *) + (* FT_PIXEL_MODE_GRAY :: *) + (* An 8-bit bitmap, generally used to represent anti-aliased glyph *) + (* images. Each pixel is stored in one byte. Note that the number *) + (* of value `gray' levels is stored in the `num_bytes' field of *) + (* the @FT_Bitmap structure (it generally is 256). *) + (* *) + (* FT_PIXEL_MODE_GRAY2 :: *) + (* A 2-bit/pixel bitmap, used to represent embedded anti-aliased *) + (* bitmaps in font files according to the OpenType specification. *) + (* We haven't found a single font using this format, however. *) + (* *) + (* FT_PIXEL_MODE_GRAY4 :: *) + (* A 4-bit/pixel bitmap, used to represent embedded anti-aliased *) + (* bitmaps in font files according to the OpenType specification. *) + (* We haven't found a single font using this format, however. *) + (* *) + (* FT_PIXEL_MODE_LCD :: *) + (* An 8-bit bitmap, used to represent RGB or BGR decimated glyph *) + (* images used for display on LCD displays; the bitmap is three *) + (* times wider than the original glyph image. See also *) + (* @FT_RENDER_MODE_LCD. *) + (* *) + (* FT_PIXEL_MODE_LCD_V :: *) + (* An 8-bit bitmap, used to represent RGB or BGR decimated glyph *) + (* images used for display on rotated LCD displays; the bitmap *) + (* is three times taller than the original glyph image. See also *) + (* @FT_RENDER_MODE_LCD_V. *) + (* *) + FT_Pixel_Mode = cint; +{$ELSE TYPE_DECL} +const + FT_PIXEL_MODE_NONE = 0; + FT_PIXEL_MODE_MONO = FT_PIXEL_MODE_NONE + 1; + FT_PIXEL_MODE_GRAY = FT_PIXEL_MODE_MONO + 1; + FT_PIXEL_MODE_GRAY2 = FT_PIXEL_MODE_GRAY + 1; + FT_PIXEL_MODE_GRAY4 = FT_PIXEL_MODE_GRAY2 + 1; + FT_PIXEL_MODE_LCD = FT_PIXEL_MODE_GRAY4 + 1; + FT_PIXEL_MODE_LCD_V = FT_PIXEL_MODE_LCD + 1; + + FT_PIXEL_MODE_MAX = FT_PIXEL_MODE_LCD_V + 1; (* do not remove *) +{$ENDIF TYPE_DECL} +{$IFDEF TYPE_DECL} + + (*************************************************************************) + (* *) + (* <Struct> *) + (* FT_Bitmap *) + (* *) + (* <Description> *) + (* A structure used to describe a bitmap or pixmap to the raster. *) + (* Note that we now manage pixmaps of various depths through the *) + (* `pixel_mode' field. *) + (* *) + (* <Fields> *) + (* rows :: The number of bitmap rows. *) + (* *) + (* width :: The number of pixels in bitmap row. *) + (* *) + (* pitch :: The pitch's absolute value is the number of bytes *) + (* taken by one bitmap row, including padding. *) + (* However, the pitch is positive when the bitmap has *) + (* a `down' flow, and negative when it has an `up' *) + (* flow. In all cases, the pitch is an offset to add *) + (* to a bitmap pointer in order to go down one row. *) + (* *) + (* buffer :: A typeless pointer to the bitmap buffer. This *) + (* value should be aligned on 32-bit boundaries in *) + (* most cases. *) + (* *) + (* num_grays :: This field is only used with *) + (* `FT_PIXEL_MODE_GRAY'; it gives the number of gray *) + (* levels used in the bitmap. *) + (* *) + (* pixel_mode :: The pixel mode, i.e., how pixel bits are stored. *) + (* See @FT_Pixel_Mode for possible values. *) + (* *) + (* palette_mode :: This field is only used with paletted pixel modes; *) + (* it indicates how the palette is stored. *) + (* *) + (* palette :: A typeless pointer to the bitmap palette; only *) + (* used for paletted pixel modes. *) + (* *) + (* <Note> *) + (* For now, the only pixel mode supported by FreeType are mono and *) + (* grays. However, drivers might be added in the future to support *) + (* more `colorful' options. *) + (* *) + (* When using pixel modes pal2, pal4 and pal8 with a void `palette' *) + (* field, a gray pixmap with respectively 4, 16, and 256 levels of *) + (* gray is assumed. This, in order to be compatible with some *) + (* embedded bitmap formats defined in the TrueType specification. *) + (* *) + (* Note that no font was found presenting such embedded bitmaps, so *) + (* this is currently completely unhandled by the library. *) + (* *) + PFT_Bitmap = ^FT_Bitmap; + FT_Bitmap = record + rows: FT_Int; + width: FT_Int; + pitch: FT_Int; + buffer: PByteArray; + num_grays: FT_Short; + pixel_mode: byte; + palette_mode: byte; + palette: pointer; + end; + + + (*************************************************************************) + (* *) + (* <Section> *) + (* outline_processing *) + (* *) + (*************************************************************************) + + + (*************************************************************************) + (* *) + (* <Struct> *) + (* FT_Outline *) + (* *) + (* <Description> *) + (* This structure is used to describe an outline to the scan-line *) + (* converter. *) + (* *) + (* <Fields> *) + (* n_contours :: The number of contours in the outline. *) + (* *) + (* n_points :: The number of points in the outline. *) + (* *) + (* points :: A pointer to an array of `n_points' FT_Vector *) + (* elements, giving the outline's point coordinates. *) + (* *) + (* tags :: A pointer to an array of `n_points' chars, giving *) + (* each outline point's type. If bit 0 is unset, the *) + (* point is `off' the curve, i.e. a Bezier control *) + (* point, while it is `on' when set. *) + (* *) + (* Bit 1 is meaningful for `off' points only. If set, *) + (* it indicates a third-order Bezier arc control point; *) + (* and a second-order control point if unset. *) + (* *) + (* contours :: An array of `n_contours' shorts, giving the end *) + (* point of each contour within the outline. For *) + (* example, the first contour is defined by the points *) + (* `0' to `contours[0]', the second one is defined by *) + (* the points `contours[0]+1' to `contours[1]', etc. *) + (* *) + (* flags :: A set of bit flags used to characterize the outline *) + (* and give hints to the scan-converter and hinter on *) + (* how to convert/grid-fit it. See FT_Outline_Flags. *) + (* *) + PFT_Outline = ^FT_Outline; + FT_Outline = record + n_contours: FT_Short; (* number of contours in glyph *) + n_points: FT_Short; (* number of points in the glyph *) + + points: PFT_VectorArray; (* the outline's points *) + tags: PByteArray; (* the points flags *) + contours: PFT_ShortArray; (* the contour end points *) + + flags: FT_Int; (* outline masks *) + end; + +{$ELSE TYPE_DECL} + + (*************************************************************************) + (* *) + (* @macro: *) + (* FT_CURVE_TAG ( flag ) *) + (* *) + function FT_CURVE_TAG(flag: byte): byte; + +const + FT_CURVE_TAG_ON = 1; + FT_CURVE_TAG_CONIC = 0; + FT_CURVE_TAG_CUBIC = 2; + + FT_CURVE_TAG_TOUCH_X = 8; // reserved for the TrueType hinter + FT_CURVE_TAG_TOUCH_Y = 16; // reserved for the TrueType hinter + + FT_CURVE_TAG_TOUCH_BOTH = ( FT_CURVE_TAG_TOUCH_X or + FT_CURVE_TAG_TOUCH_Y ); +{$ENDIF TYPE_DECL} +{$IFDEF TYPE_DECL} + + (*************************************************************************) + (* *) + (* <FuncType> *) + (* FT_Outline_MoveToFunc *) + (* *) + (* <Description> *) + (* A function pointer type used to describe the signature of a `move *) + (* to' function during outline walking/decomposition. *) + (* *) + (* A `move to' is emitted to start a new contour in an outline. *) + (* *) + (* <Input> *) + (* to :: A pointer to the target point of the `move to'. *) + (* *) + (* user :: A typeless pointer which is passed from the caller of the *) + (* decomposition function. *) + (* *) + (* <Return> *) + (* Error code. 0 means success. *) + (* *) + FT_Outline_MoveToFunc = function(to_: {const} PFT_Vector; + user: Pointer): cint; cdecl; + + + (*************************************************************************) + (* *) + (* <FuncType> *) + (* FT_Outline_LineToFunc *) + (* *) + (* <Description> *) + (* A function pointer type used to describe the signature of a `line *) + (* to' function during outline walking/decomposition. *) + (* *) + (* A `line to' is emitted to indicate a segment in the outline. *) + (* *) + (* <Input> *) + (* to :: A pointer to the target point of the `line to'. *) + (* *) + (* user :: A typeless pointer which is passed from the caller of the *) + (* decomposition function. *) + (* *) + (* <Return> *) + (* Error code. 0 means success. *) + (* *) + FT_Outline_LineToFunc = function(to_: {const} PFT_Vector; + user: Pointer): cint; cdecl; + + + (*************************************************************************) + (* *) + (* <FuncType> *) + (* FT_Outline_ConicToFunc *) + (* *) + (* <Description> *) + (* A function pointer type use to describe the signature of a `conic *) + (* to' function during outline walking/decomposition. *) + (* *) + (* A `conic to' is emitted to indicate a second-order Bézier arc in *) + (* the outline. *) + (* *) + (* <Input> *) + (* control :: An intermediate control point between the last position *) + (* and the new target in `to'. *) + (* *) + (* to :: A pointer to the target end point of the conic arc. *) + (* *) + (* user :: A typeless pointer which is passed from the caller of *) + (* the decomposition function. *) + (* *) + (* <Return> *) + (* Error code. 0 means success. *) + (* *) + FT_Outline_ConicToFunc = function(control: {const} PFT_Vector; + to_: {const} PFT_Vector; + user: Pointer): cint; cdecl; + + + (*************************************************************************) + (* *) + (* <FuncType> *) + (* FT_Outline_CubicToFunc *) + (* *) + (* <Description> *) + (* A function pointer type used to describe the signature of a `cubic *) + (* to' function during outline walking/decomposition. *) + (* *) + (* A `cubic to' is emitted to indicate a third-order Bézier arc. *) + (* *) + (* <Input> *) + (* control1 :: A pointer to the first Bézier control point. *) + (* *) + (* control2 :: A pointer to the second Bézier control point. *) + (* *) + (* to :: A pointer to the target end point. *) + (* *) + (* user :: A typeless pointer which is passed from the caller of *) + (* the decomposition function. *) + (* *) + (* <Return> *) + (* Error code. 0 means success. *) + (* *) + FT_Outline_CubicToFunc = function( control1: {const} PFT_Vector; + control2: {const} PFT_Vector; + to_: {const} PFT_Vector; + user: Pointer ): cint; cdecl; + + + (*************************************************************************) + (* *) + (* <Struct> *) + (* FT_Outline_Funcs *) + (* *) + (* <Description> *) + (* A structure to hold various function pointers used during outline *) + (* decomposition in order to emit segments, conic, and cubic Béziers, *) + (* as well as `move to' and `close to' operations. *) + (* *) + (* <Fields> *) + (* move_to :: The `move to' emitter. *) + (* *) + (* line_to :: The segment emitter. *) + (* *) + (* conic_to :: The second-order Bézier arc emitter. *) + (* *) + (* cubic_to :: The third-order Bézier arc emitter. *) + (* *) + (* shift :: The shift that is applied to coordinates before they *) + (* are sent to the emitter. *) + (* *) + (* delta :: The delta that is applied to coordinates before they *) + (* are sent to the emitter, but after the shift. *) + (* *) + (* <Note> *) + (* The point coordinates sent to the emitters are the transformed *) + (* version of the original coordinates (this is important for high *) + (* accuracy during scan-conversion). The transformation is simple: *) + (* *) + (* { *) + (* x' = (x << shift) - delta *) + (* y' = (x << shift) - delta *) + (* } *) + (* *) + (* Set the value of `shift' and `delta' to 0 to get the original *) + (* point coordinates. *) + (* *) + PFT_Outline_Funcs = ^FT_Outline_Funcs; + FT_Outline_Funcs = record + move_to: FT_Outline_MoveToFunc; + line_to: FT_Outline_LineToFunc; + conic_to: FT_Outline_ConicToFunc; + cubic_to: FT_Outline_CubicToFunc; + + shift: cint; + delta: FT_Pos; + end; + + + (*************************************************************************) + (* *)
+ (* <Macro> *)
+ (* FT_IMAGE_TAG *)
+ (* *)
+ (* <Description> *)
+ (* This macro converts four-letter tags to an unsigned long type. *)
+ (* *)
+ (* <Note> *)
+ (* Since many 16-bit compilers don't like 32-bit enumerations, you *)
+ (* should redefine this macro in case of problems to something like *)
+ (* this: *)
+ (* *)
+ (* { *)
+ (* #define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 ) value *)
+ (* } *)
+ (* *)
+ (* to get a simple enumeration without assigning special numbers. *)
+ (* *)
+ {
+ #define FT_IMAGE_TAG( value, _x1, _x2, _x3, _x4 ) \
+ value = ( ( (unsigned long)_x1 << 24 ) | \
+ ( (unsigned long)_x2 << 16 ) | \
+ ( (unsigned long)_x3 << 8 ) | \
+ (unsigned long)_x4 )
+ }
+
+ (*************************************************************************) + (* *) + (* <Enum> *) + (* FT_Glyph_Format *) + (* *) + (* <Description> *) + (* An enumeration type used to describe the format of a given glyph *) + (* image. Note that this version of FreeType only supports two image *) + (* formats, even though future font drivers will be able to register *) + (* their own format. *) + (* *) + (* <Values> *) + (* FT_GLYPH_FORMAT_NONE :: *) + (* The value 0 is reserved and does describe a glyph format. *) + (* *) + (* FT_GLYPH_FORMAT_COMPOSITE :: *) + (* The glyph image is a composite of several other images. This *) + (* format is _only_ used with @FT_LOAD_NO_RECURSE, and is used to *) + (* report compound glyphs (like accented characters). *) + (* *) + (* FT_GLYPH_FORMAT_BITMAP :: *) + (* The glyph image is a bitmap, and can be described as an *) + (* @FT_Bitmap. You generally need to access the `bitmap' field of *) + (* the @FT_GlyphSlotRec structure to read it. *) + (* *) + (* FT_GLYPH_FORMAT_OUTLINE :: *) + (* The glyph image is a vertorial outline made of line segments *) + (* and Bezier arcs; it can be described as an @FT_Outline; you *) + (* generally want to access the `outline' field of the *) + (* @FT_GlyphSlotRec structure to read it. *) + (* *) + (* FT_GLYPH_FORMAT_PLOTTER :: *) + (* The glyph image is a vectorial path with no inside/outside *) + (* contours. Some Type 1 fonts, like those in the Hershey family, *) + (* contain glyphs in this format. These are described as *) + (* @FT_Outline, but FreeType isn't currently capable of rendering *) + (* them correctly. *) + (* *) + // Note: enums are 32 bit on x86 AND x86_64 + FT_Glyph_Format = cuint32; // 32 bit enum of FT_IMAGE_TAG +{$ELSE TYPE_DECL} +const + FT_GLYPH_FORMAT_NONE = (Ord(#0) shl 24) or + (Ord(#0) shl 16) or
+ (Ord(#0) shl 8) or
+ (Ord(#0) shl 0); + + FT_GLYPH_FORMAT_COMPOSITE = (Ord('c') shl 24) or + (Ord('o') shl 16) or
+ (Ord('m') shl 8) or
+ (Ord('p') shl 0); + + FT_GLYPH_FORMAT_BITMAP = (Ord('b') shl 24) or + (Ord('i') shl 16) or
+ (Ord('t') shl 8) or
+ (Ord('s') shl 0); + + FT_GLYPH_FORMAT_OUTLINE = (Ord('o') shl 24) or + (Ord('u') shl 16) or
+ (Ord('t') shl 8) or
+ (Ord('l') shl 0); + + FT_GLYPH_FORMAT_PLOTTER = (Ord('p') shl 24) or + (Ord('l') shl 16) or
+ (Ord('o') shl 8) or
+ (Ord('t') shl 0); + +{$ENDIF TYPE_DECL} + + (*************************************************************************) + (*************************************************************************) + (*************************************************************************) + (***** *****) + (***** R A S T E R D E F I N I T I O N S *****) + (***** *****) + (*************************************************************************) + (*************************************************************************) + (*************************************************************************) + + + (*************************************************************************) + (* *) + (* A raster is a scan converter, in charge of rendering an outline into *) + (* a a bitmap. This section contains the public API for rasters. *) + (* *) + (* Note that in FreeType 2, all rasters are now encapsulated within *) + (* specific modules called `renderers'. See `freetype/ftrender.h' for *) + (* more details on renderers. *) + (* *) + (*************************************************************************) + + + (*************************************************************************) + (* *) + (* <Section> *) + (* raster *) + (* *) + (* <Title> *) + (* Scanline Converter *) + (* *) + (* <Abstract> *) + (* How vectorial outlines are converted into bitmaps and pixmaps. *) + (* *) + (* <Description> *) + (* This section contains technical definitions. *) + (* *) + (*************************************************************************) + +{$IFDEF TYPE_DECL} + + (*************************************************************************) + (* *) + (* <Type> *) + (* FT_Raster *) + (* *) + (* <Description> *) + (* A handle (pointer) to a raster object. Each object can be used *) + (* independently to convert an outline into a bitmap or pixmap. *) + (* *) + FT_Raster = Pointer; + + + (*************************************************************************) + (* *) + (* <Struct> *) + (* FT_Span *) + (* *) + (* <Description> *) + (* A structure used to model a single span of gray (or black) pixels *) + (* when rendering a monochrome or anti-aliased bitmap. *) + (* *) + (* <Fields> *) + (* x :: The span's horizontal start position. *) + (* *) + (* len :: The span's length in pixels. *) + (* *) + (* coverage :: The span color/coverage, ranging from 0 (background) *) + (* to 255 (foreground). Only used for anti-aliased *) + (* rendering. *) + (* *) + (* <Note> *) + (* This structure is used by the span drawing callback type named *) + (* @FT_SpanFunc which takes the y-coordinate of the span as a *) + (* a parameter. *) + (* *) + (* The coverage value is always between 0 and 255. *) + (* *) + PFT_Span = ^FT_Span; + FT_Span = record + x: cshort; + len: cushort; + coverage: cuchar; + end; + + + (*************************************************************************) + (* *) + (* <FuncType> *) + (* FT_SpanFunc *) + (* *) + (* <Description> *) + (* A function used as a call-back by the anti-aliased renderer in *) + (* order to let client applications draw themselves the gray pixel *) + (* spans on each scan line. *) + (* *) + (* <Input> *) + (* y :: The scanline's y-coordinate. *) + (* *) + (* count :: The number of spans to draw on this scanline. *) + (* *) + (* spans :: A table of `count' spans to draw on the scanline. *) + (* *) + (* user :: User-supplied data that is passed to the callback. *) + (* *) + (* <Note> *) + (* This callback allows client applications to directly render the *) + (* gray spans of the anti-aliased bitmap to any kind of surfaces. *) + (* *) + (* This can be used to write anti-aliased outlines directly to a *) + (* given background bitmap, and even perform translucency. *) + (* *) + (* Note that the `count' field cannot be greater than a fixed value *) + (* defined by the `FT_MAX_GRAY_SPANS' configuration macro in *) + (* `ftoption.h'. By default, this value is set to 32, which means *) + (* that if there are more than 32 spans on a given scanline, the *) + (* callback is called several times with the same `y' parameter in *) + (* order to draw all callbacks. *) + (* *) + (* Otherwise, the callback is only called once per scan-line, and *) + (* only for those scanlines that do have `gray' pixels on them. *) + (* *) + FT_SpanFunc = procedure(y: cint; + count: cint; + spans: {const} PFT_Span; + user: Pointer ); cdecl; + + + (*************************************************************************) + (* *) + (* <FuncType> *) + (* FT_Raster_BitTest_Func *) + (* *) + (* <Description> *) + (* THIS TYPE IS DEPRECATED. DO NOT USE IT. *) + (* *) + (* A function used as a call-back by the monochrome scan-converter *) + (* to test whether a given target pixel is already set to the drawing *) + (* `color'. These tests are crucial to implement drop-out control *) + (* per-se the TrueType spec. *) + (* *) + (* <Input> *) + (* y :: The pixel's y-coordinate. *) + (* *) + (* x :: The pixel's x-coordinate. *) + (* *) + (* user :: User-supplied data that is passed to the callback. *) + (* *) + (* <Return> *) + (* 1 if the pixel is `set', 0 otherwise. *) + (* *) + FT_Raster_BitTest_Func = function(y: cint; + x: cint; + user: Pointer): cint; cdecl; + + + (*************************************************************************) + (* *) + (* <FuncType> *) + (* FT_Raster_BitSet_Func *) + (* *) + (* <Description> *) + (* THIS TYPE IS DEPRECATED. DO NOT USE IT. *) + (* *) + (* A function used as a call-back by the monochrome scan-converter *) + (* to set an individual target pixel. This is crucial to implement *) + (* drop-out control according to the TrueType specification. *) + (* *) + (* <Input> *) + (* y :: The pixel's y-coordinate. *) + (* *) + (* x :: The pixel's x-coordinate. *) + (* *) + (* user :: User-supplied data that is passed to the callback. *) + (* *) + (* <Return> *) + (* 1 if the pixel is `set', 0 otherwise. *) + (* *) + FT_Raster_BitSet_Func = procedure(y: cint; + x: cint; + user: Pointer ); cdecl; + + + (*************************************************************************) + (* *) + (* <Enum> *) + (* FT_RASTER_FLAG_XXX *) + (* *) + (* <Description> *) + (* A list of bit flag constants as used in the `flags' field of a *) + (* @FT_Raster_Params structure. *) + (* *) + (* <Values> *) + (* FT_RASTER_FLAG_DEFAULT :: This value is 0. *) + (* *) + (* FT_RASTER_FLAG_AA :: This flag is set to indicate that an *) + (* anti-aliased glyph image should be *) + (* generated. Otherwise, it will be *) + (* monochrome (1-bit). *) + (* *) + (* FT_RASTER_FLAG_DIRECT :: This flag is set to indicate direct *) + (* rendering. In this mode, client *) + (* applications must provide their own span *) + (* callback. This lets them directly *) + (* draw or compose over an existing bitmap. *) + (* If this bit is not set, the target *) + (* pixmap's buffer _must_ be zeroed before *) + (* rendering. *) + (* *) + (* Note that for now, direct rendering is *) + (* only possible with anti-aliased glyphs. *) + (* *) + (* FT_RASTER_FLAG_CLIP :: This flag is only used in direct *) + (* rendering mode. If set, the output will *) + (* be clipped to a box specified in the *) + (* `clip_box' field of the *) + (* @FT_Raster_Params structure. *) + (* *) + (* Note that by default, the glyph bitmap *) + (* is clipped to the target pixmap, except *) + (* in direct rendering mode where all spans *) + (* are generated if no clipping box is set. *) + (* *) +{$ELSE TYPE_DECL} +const + FT_RASTER_FLAG_DEFAULT = $0; + FT_RASTER_FLAG_AA = $1; + FT_RASTER_FLAG_DIRECT = $2; + FT_RASTER_FLAG_CLIP = $4; + +{$ENDIF TYPE_DECL} +{$IFDEF TYPE_DECL} + + (*************************************************************************) + (* *) + (* <Struct> *) + (* FT_Raster_Params *) + (* *) + (* <Description> *) + (* A structure to hold the arguments used by a raster's render *) + (* function. *) + (* *) + (* <Fields> *) + (* target :: The target bitmap. *) + (* *) + (* source :: A pointer to the source glyph image (e.g., an *) + (* @FT_Outline). *) + (* *) + (* flags :: The rendering flags. *) + (* *) + (* gray_spans :: The gray span drawing callback. *) + (* *) + (* black_spans :: The black span drawing callback. *) + (* *) + (* bit_test :: The bit test callback. UNIMPLEMENTED! *) + (* *) + (* bit_set :: The bit set callback. UNIMPLEMENTED! *) + (* *) + (* user :: User-supplied data that is passed to each drawing *) + (* callback. *) + (* *) + (* clip_box :: An optional clipping box. It is only used in *) + (* direct rendering mode. Note that coordinates here *) + (* should be expressed in _integer_ pixels (and not in *) + (* 26.6 fixed-point units). *) + (* *) + (* <Note> *) + (* An anti-aliased glyph bitmap is drawn if the @FT_RASTER_FLAG_AA *) + (* bit flag is set in the `flags' field, otherwise a monochrome *) + (* bitmap is generated. *) + (* *) + (* If the @FT_RASTER_FLAG_DIRECT bit flag is set in `flags', the *) + (* raster will call the `gray_spans' callback to draw gray pixel *) + (* spans, in the case of an aa glyph bitmap, it will call *) + (* `black_spans', and `bit_test' and `bit_set' in the case of a *) + (* monochrome bitmap. This allows direct composition over a *) + (* pre-existing bitmap through user-provided callbacks to perform the *) + (* span drawing/composition. *) + (* *) + (* Note that the `bit_test' and `bit_set' callbacks are required when *) + (* rendering a monochrome bitmap, as they are crucial to implement *) + (* correct drop-out control as defined in the TrueType specification. *) + (* *) + PFT_Raster_Params = ^FT_Raster_Params; + FT_Raster_Params = record + target: {const} PFT_Bitmap; + source: {const} Pointer; + flags: cint; + gray_spans: FT_SpanFunc; + black_spans: FT_SpanFunc; + bit_test: FT_Raster_BitTest_Func; (* doesn't work! *) + bit_set: FT_Raster_BitSet_Func; (* doesn't work! *) + user: Pointer; + clip_box: FT_BBox; + end; + +{$ENDIF TYPE_DECL} + + diff --git a/cmake/src/lib/freetype/ftoutln.inc b/cmake/src/lib/freetype/ftoutln.inc new file mode 100644 index 00000000..997c6cb3 --- /dev/null +++ b/cmake/src/lib/freetype/ftoutln.inc @@ -0,0 +1,497 @@ +(***************************************************************************) +(* *) +(* ftoutln.h *) +(* *) +(* Support for the FT_Outline type used to store glyph shapes of *) +(* most scalable font formats (specification). *) +(* *) +(* Copyright 1996-2001, 2002, 2003, 2005, 2006, 2007 by *) +(* David Turner, Robert Wilhelm, and Werner Lemberg. *) +(* *) +(* This file is part of the FreeType project, and may only be used, *) +(* modified, and distributed under the terms of the FreeType project *) +(* license, LICENSE.TXT. By continuing to use, modify, or distribute *) +(* this file you indicate that you have read the license and *) +(* understand and accept it fully. *) +(* *) +(***************************************************************************) +(***************************************************************************) +(* Pascal port by the UltraStar Deluxe Team *) +(***************************************************************************) + + + (*************************************************************************) + (* *) + (* <Section> *) + (* outline_processing *) + (* *) + (* <Title> *) + (* Outline Processing *) + (* *) + (* <Abstract> *) + (* Functions to create, transform, and render vectorial glyph images. *) + (* *) + (* <Description> *) + (* This section contains routines used to create and destroy scalable *) + (* glyph images known as `outlines'. These can also be measured, *) + (* transformed, and converted into bitmaps and pixmaps. *) + (* *) + (* <Order> *) + (* FT_Outline *) + (* FT_OUTLINE_FLAGS *) + (* FT_Outline_New *) + (* FT_Outline_Done *) + (* FT_Outline_Copy *) + (* FT_Outline_Translate *) + (* FT_Outline_Transform *) + (* FT_Outline_Embolden *) + (* FT_Outline_Reverse *) + (* FT_Outline_Check *) + (* *) + (* FT_Outline_Get_CBox *) + (* FT_Outline_Get_BBox *) + (* *) + (* FT_Outline_Get_Bitmap *) + (* FT_Outline_Render *) + (* *) + (* FT_Outline_Decompose *) + (* FT_Outline_Funcs *) + (* FT_Outline_MoveTo_Func *) + (* FT_Outline_LineTo_Func *) + (* FT_Outline_ConicTo_Func *) + (* FT_Outline_CubicTo_Func *) + (* *) + (*************************************************************************) + +{$IFNDEF TYPE_DECL} + + (*************************************************************************) + (* *) + (* <Function> *) + (* FT_Outline_Decompose *) + (* *) + (* <Description> *) + (* Walks over an outline's structure to decompose it into individual *) + (* segments and Bézier arcs. This function is also able to emit *) + (* `move to' and `close to' operations to indicate the start and end *) + (* of new contours in the outline. *) + (* *) + (* <Input> *) + (* outline :: A pointer to the source target. *) + (* *) + (* func_interface :: A table of `emitters', i.e,. function pointers *) + (* called during decomposition to indicate path *) + (* operations. *) + (* *) + (* <InOut> *) + (* user :: A typeless pointer which is passed to each *) + (* emitter during the decomposition. It can be *) + (* used to store the state during the *) + (* decomposition. *) + (* *) + (* <Return> *) + (* FreeType error code. 0 means success. *) + (* *) + function FT_Outline_Decompose( + outline: PFT_Outline; + func_interface: {const} PFT_Outline_Funcs; + user: Pointer): FT_Error; + cdecl; external ft_lib name 'FT_Outline_Decompose'; + + + (*************************************************************************) + (* *) + (* <Function> *) + (* FT_Outline_New *) + (* *) + (* <Description> *) + (* Creates a new outline of a given size. *) + (* *) + (* <Input> *) + (* library :: A handle to the library object from where the *) + (* outline is allocated. Note however that the new *) + (* outline will *not* necessarily be *freed*, when *) + (* destroying the library, by @FT_Done_FreeType. *) + (* *) + (* numPoints :: The maximal number of points within the outline. *) + (* *) + (* numContours :: The maximal number of contours within the outline. *) + (* *) + (* <Output> *) + (* anoutline :: A handle to the new outline. NULL in case of *) + (* error. *) + (* *) + (* <Return> *) + (* FreeType error code. 0 means success. *) + (* *) + (* <Note> *) + (* The reason why this function takes a `library' parameter is simply *) + (* to use the library's memory allocator. *) + (* *) + function FT_Outline_New( + library_: FT_Library; + numPoints: FT_UInt; + numContours: FT_Int; + anoutline: PFT_Outline): FT_Error; + cdecl; external ft_lib name 'FT_Outline_New'; + + + (*************************************************************************) + (* *) + (* <Function> *) + (* FT_Outline_Done *) + (* *) + (* <Description> *) + (* Destroys an outline created with @FT_Outline_New. *) + (* *) + (* <Input> *) + (* library :: A handle of the library object used to allocate the *) + (* outline. *) + (* *) + (* outline :: A pointer to the outline object to be discarded. *) + (* *) + (* <Return> *) + (* FreeType error code. 0 means success. *) + (* *) + (* <Note> *) + (* If the outline's `owner' field is not set, only the outline *) + (* descriptor will be released. *) + (* *) + (* The reason why this function takes an `library' parameter is *) + (* simply to use ft_mem_free(). *) + (* *) + function FT_Outline_Done(library_: FT_Library; + outline: PFT_Outline): FT_Error; + cdecl; external ft_lib name 'FT_Outline_Done'; + + + (*************************************************************************) + (* *) + (* <Function> *) + (* FT_Outline_Check *) + (* *) + (* <Description> *) + (* Check the contents of an outline descriptor. *) + (* *) + (* <Input> *) + (* outline :: A handle to a source outline. *) + (* *) + (* <Return> *) + (* FreeType error code. 0 means success. *) + (* *) + function FT_Outline_Check( outline: PFT_Outline ): FT_Error; + cdecl; external ft_lib name 'FT_Outline_Check'; + + + (*************************************************************************) + (* *) + (* <Function> *) + (* FT_Outline_Get_CBox *) + (* *) + (* <Description> *) + (* Returns an outline's `control box'. The control box encloses all *) + (* the outline's points, including Bézier control points. Though it *) + (* coincides with the exact bounding box for most glyphs, it can be *) + (* slightly larger in some situations (like when rotating an outline *) + (* which contains Bézier outside arcs). *) + (* *) + (* Computing the control box is very fast, while getting the bounding *) + (* box can take much more time as it needs to walk over all segments *) + (* and arcs in the outline. To get the latter, you can use the *) + (* `ftbbox' component which is dedicated to this single task. *) + (* *) + (* <Input> *) + (* outline :: A pointer to the source outline descriptor. *) + (* *) + (* <Output> *) + (* acbox :: The outline's control box. *) + (* *) + procedure FT_Outline_Get_CBox( + outline: {const} PFT_Outline; + acbox: PFT_BBox); + cdecl; external ft_lib name 'FT_Outline_Get_CBox'; + + + (*************************************************************************) + (* *) + (* <Function> *) + (* FT_Outline_Translate *) + (* *) + (* <Description> *) + (* Applies a simple translation to the points of an outline. *) + (* *) + (* <InOut> *) + (* outline :: A pointer to the target outline descriptor. *) + (* *) + (* <Input> *) + (* xOffset :: The horizontal offset. *) + (* *) + (* yOffset :: The vertical offset. *) + (* *) + procedure FT_Outline_Translate( + outline: {const} PFT_Outline; + xOffset: FT_Pos; + yOffset: FT_Pos); + cdecl; external ft_lib name 'FT_Outline_Translate'; + + + (*************************************************************************) + (* *) + (* <Function> *) + (* FT_Outline_Copy *) + (* *) + (* <Description> *) + (* Copies an outline into another one. Both objects must have the *) + (* same sizes (number of points & number of contours) when this *) + (* function is called. *) + (* *) + (* <Input> *) + (* source :: A handle to the source outline. *) + (* *) + (* <Output> *) + (* target :: A handle to the target outline. *) + (* *) + (* <Return> *) + (* FreeType error code. 0 means success. *) + (* *) + function FT_Outline_Copy( + source: {const} PFT_Outline; + target: PFT_Outline): FT_Error; + cdecl; external ft_lib name 'FT_Outline_Copy'; + + + (*************************************************************************) + (* *) + (* <Function> *) + (* FT_Outline_Transform *) + (* *) + (* <Description> *) + (* Applies a simple 2x2 matrix to all of an outline's points. Useful *) + (* for applying rotations, slanting, flipping, etc. *) + (* *) + (* <InOut> *) + (* outline :: A pointer to the target outline descriptor. *) + (* *) + (* <Input> *) + (* matrix :: A pointer to the transformation matrix. *) + (* *) + (* <Note> *) + (* You can use @FT_Outline_Translate if you need to translate the *) + (* outline's points. *) + (* *) + procedure FT_Outline_Transform( + outline: {const} PFT_Outline; + matrix: {const} PFT_Matrix); + cdecl; external ft_lib name 'FT_Outline_Transform'; + + + (*************************************************************************) + (* *) + (* <Function> *) + (* FT_Outline_Embolden *) + (* *) + (* <Description> *) + (* Emboldens an outline. The new outline will be at most 4 times *) + (* `strength' pixels wider and higher. You may think of the left and *) + (* bottom borders as unchanged. *) + (* *) + (* Negative `strength' values to reduce the outline thickness are *) + (* possible also. *) + (* *) + (* <InOut> *) + (* outline :: A handle to the target outline. *) + (* *) + (* <Input> *) + (* strength :: How strong the glyph is emboldened. Expressed in *) + (* 26.6 pixel format. *) + (* *) + (* <Return> *) + (* FreeType error code. 0 means success. *) + (* *) + (* <Note> *) + (* The used algorithm to increase or decrease the thickness of the *) + (* glyph doesn't change the number of points; this means that certain *) + (* situations like acute angles or intersections are sometimes *) + (* handled incorrectly. *) + (* *) + (* Example call: *) + (* *) + (* { *) + (* FT_Load_Glyph( face, index, FT_LOAD_DEFAULT ); *) + (* if ( face->slot->format == FT_GLYPH_FORMAT_OUTLINE ) *) + (* FT_Outline_Embolden( &face->slot->outline, strength ); *) + (* } *) + (* *) + function FT_Outline_Embolden( + outline: PFT_Outline; + strength: FT_Pos): FT_Error; + cdecl; external ft_lib name 'FT_Outline_Embolden'; + + + (*************************************************************************) + (* *) + (* <Function> *) + (* FT_Outline_Reverse *) + (* *) + (* <Description> *) + (* Reverses the drawing direction of an outline. This is used to *) + (* ensure consistent fill conventions for mirrored glyphs. *) + (* *) + (* <InOut> *) + (* outline :: A pointer to the target outline descriptor. *) + (* *) + (* <Note> *) + (* This functions toggles the bit flag @FT_OUTLINE_REVERSE_FILL in *) + (* the outline's `flags' field. *) + (* *) + (* It shouldn't be used by a normal client application, unless it *) + (* knows what it is doing. *) + (* *) + procedure FT_Outline_Reverse( outline: PFT_Outline ); + cdecl; external ft_lib name 'FT_Outline_Reverse'; + + + (*************************************************************************) + (* *) + (* <Function> *) + (* FT_Outline_Get_Bitmap *) + (* *) + (* <Description> *) + (* Renders an outline within a bitmap. The outline's image is simply *) + (* OR-ed to the target bitmap. *) + (* *) + (* <Input> *) + (* library :: A handle to a FreeType library object. *) + (* *) + (* outline :: A pointer to the source outline descriptor. *) + (* *) + (* <InOut> *) + (* abitmap :: A pointer to the target bitmap descriptor. *) + (* *) + (* <Return> *) + (* FreeType error code. 0 means success. *) + (* *) + (* <Note> *) + (* This function does NOT CREATE the bitmap, it only renders an *) + (* outline image within the one you pass to it! *) + (* *) + (* It will use the raster corresponding to the default glyph format. *) + (* *) + function FT_Outline_Get_Bitmap( + library_: FT_Library; + outline: PFT_Outline; + abitmap: {const} PFT_Bitmap): FT_Error; + cdecl; external ft_lib name 'FT_Outline_Get_Bitmap'; + + + (*************************************************************************) + (* *) + (* <Function> *) + (* FT_Outline_Render *) + (* *) + (* <Description> *) + (* Renders an outline within a bitmap using the current scan-convert. *) + (* This functions uses an @FT_Raster_Params structure as an argument, *) + (* allowing advanced features like direct composition, translucency, *) + (* etc. *) + (* *) + (* <Input> *) + (* library :: A handle to a FreeType library object. *) + (* *) + (* outline :: A pointer to the source outline descriptor. *) + (* *) + (* <InOut> *) + (* params :: A pointer to an @FT_Raster_Params structure used to *) + (* describe the rendering operation. *) + (* *) + (* <Return> *) + (* FreeType error code. 0 means success. *) + (* *) + (* <Note> *) + (* You should know what you are doing and how @FT_Raster_Params works *) + (* to use this function. *) + (* *) + (* The field `params.source' will be set to `outline' before the scan *) + (* converter is called, which means that the value you give to it is *) + (* actually ignored. *) + (* *) + function FT_Outline_Render( + library_: FT_Library; + outline: PFT_Outline; + params: PFT_Raster_Params): FT_Error; + cdecl; external ft_lib name 'FT_Outline_Render'; + +{$ENDIF TYPE_DECL} + + (************************************************************************** + * + * @enum: + * FT_Orientation + * + * @description: + * A list of values used to describe an outline's contour orientation. + * + * The TrueType and Postscript specifications use different conventions + * to determine whether outline contours should be filled or unfilled. + * + * @values: + * FT_ORIENTATION_TRUETYPE :: + * According to the TrueType specification, clockwise contours must + * be filled, and counter-clockwise ones must be unfilled. + * + * FT_ORIENTATION_POSTSCRIPT :: + * According to the Postscript specification, counter-clockwise contours + * must be filled, and clockwise ones must be unfilled. + * + * FT_ORIENTATION_FILL_RIGHT :: + * This is identical to @FT_ORIENTATION_TRUETYPE, but is used to + * remember that in TrueType, everything that is to the right of + * the drawing direction of a contour must be filled. + * + * FT_ORIENTATION_FILL_LEFT :: + * This is identical to @FT_ORIENTATION_POSTSCRIPT, but is used to + * remember that in Postscript, everything that is to the left of + * the drawing direction of a contour must be filled. + * + * FT_ORIENTATION_NONE :: + * The orientation cannot be determined. That is, different parts of + * the glyph have different orientation. + * + *) +{$IFDEF TYPE_DECL} + FT_Orientation = cint; +{$ELSE TYPE_DECL} +const + FT_ORIENTATION_TRUETYPE = 0; + FT_ORIENTATION_POSTSCRIPT = 1; + FT_ORIENTATION_FILL_RIGHT = FT_ORIENTATION_TRUETYPE; + FT_ORIENTATION_FILL_LEFT = FT_ORIENTATION_POSTSCRIPT; + FT_ORIENTATION_NONE = FT_ORIENTATION_FILL_LEFT+1; + + (************************************************************************** + * + * @function: + * FT_Outline_Get_Orientation + * + * @description: + * This function analyzes a glyph outline and tries to compute its + * fill orientation (see @FT_Orientation). This is done by computing + * the direction of each global horizontal and/or vertical extrema + * within the outline. + * + * Note that this will return @FT_ORIENTATION_TRUETYPE for empty + * outlines. + * + * @input: + * outline :: + * A handle to the source outline. + * + * @return: + * The orientation. + * + *) + function FT_Outline_Get_Orientation( outline: PFT_Outline ): FT_Orientation; + cdecl; external ft_lib name 'FT_Outline_Get_Orientation'; + +{$ENDIF TYPE_DECL} + diff --git a/cmake/src/lib/freetype/ftstroke.inc b/cmake/src/lib/freetype/ftstroke.inc new file mode 100644 index 00000000..bf8a00ae --- /dev/null +++ b/cmake/src/lib/freetype/ftstroke.inc @@ -0,0 +1,711 @@ +{***************************************************************************} +{* *} +{* ftstroke.h *} +{* *} +{* FreeType path stroker (specification). *} +{* *} +{* Copyright 2002, 2003, 2004, 2005, 2006 by *} +{* David Turner, Robert Wilhelm, and Werner Lemberg. *} +{* *} +{* This file is part of the FreeType project, and may only be used, *} +{* modified, and distributed under the terms of the FreeType project *} +{* license, LICENSE.TXT. By continuing to use, modify, or distribute *} +{* this file you indicate that you have read the license and *} +{* understand and accept it fully. *} +{* *} +{***************************************************************************} +(***************************************************************************) +(* Pascal port by the UltraStar Deluxe Team *) +(***************************************************************************) + + {************************************************************************ + * + * @section: + * glyph_stroker + * + * @title: + * Glyph Stroker + * + * @abstract: + * Generating bordered and stroked glyphs. + * + * @description: + * This component generates stroked outlines of a given vectorial + * glyph. It also allows you to retrieve the `outside' and/or the + * `inside' borders of the stroke. + * + * This can be useful to generate `bordered' glyph, i.e., glyphs + * displayed with a coloured (and anti-aliased) border around their + * shape. + *} + +{$IFDEF TYPE_DECL} + + {************************************************************** + * + * @type: + * FT_Stroker + * + * @description: + * Opaque handler to a path stroker object. + *} + FT_Stroker = Pointer; + + + {************************************************************** + * + * @enum: + * FT_Stroker_LineJoin + * + * @description: + * These values determine how two joining lines are rendered + * in a stroker. + * + * @values: + * FT_STROKER_LINEJOIN_ROUND :: + * Used to render rounded line joins. Circular arcs are used + * to join two lines smoothly. + * + * FT_STROKER_LINEJOIN_BEVEL :: + * Used to render beveled line joins; i.e., the two joining lines + * are extended until they intersect. + * + * FT_STROKER_LINEJOIN_MITER :: + * Same as beveled rendering, except that an additional line + * break is added if the angle between the two joining lines + * is too closed (this is useful to avoid unpleasant spikes + * in beveled rendering). + *} + FT_Stroker_LineJoin = cint; +{$ELSE TYPE_DECL} +const + FT_STROKER_LINEJOIN_ROUND = 0; + FT_STROKER_LINEJOIN_BEVEL = 1; + FT_STROKER_LINEJOIN_MITER = 2; + +{$ENDIF TYPE_DECL} +{$IFDEF TYPE_DECL} + + {************************************************************** + * + * @enum: + * FT_Stroker_LineCap + * + * @description: + * These values determine how the end of opened sub-paths are + * rendered in a stroke. + * + * @values: + * FT_STROKER_LINECAP_BUTT :: + * The end of lines is rendered as a full stop on the last + * point itself. + * + * FT_STROKER_LINECAP_ROUND :: + * The end of lines is rendered as a half-circle around the + * last point. + * + * FT_STROKER_LINECAP_SQUARE :: + * The end of lines is rendered as a square around the + * last point. + *} + FT_Stroker_LineCap = cint; +{$ELSE TYPE_DECL} +const + FT_STROKER_LINECAP_BUTT = 0; + FT_STROKER_LINECAP_ROUND = 1; + FT_STROKER_LINECAP_SQUARE = 2; + +{$ENDIF TYPE_DECL} +{$IFDEF TYPE_DECL} + + {************************************************************** + * + * @enum: + * FT_StrokerBorder + * + * @description: + * These values are used to select a given stroke border + * in @FT_Stroker_GetBorderCounts and @FT_Stroker_ExportBorder. + * + * @values: + * FT_STROKER_BORDER_LEFT :: + * Select the left border, relative to the drawing direction. + * + * FT_STROKER_BORDER_RIGHT :: + * Select the right border, relative to the drawing direction. + * + * @note: + * Applications are generally interested in the `inside' and `outside' + * borders. However, there is no direct mapping between these and the + * `left' and `right' ones, since this really depends on the glyph's + * drawing orientation, which varies between font formats. + * + * You can however use @FT_Outline_GetInsideBorder and + * @FT_Outline_GetOutsideBorder to get these. + *} + FT_StrokerBorder = cint; +{$ELSE TYPE_DECL} +const + FT_STROKER_BORDER_LEFT = 0; + FT_STROKER_BORDER_RIGHT = 1; + + + {************************************************************** + * + * @function: + * FT_Outline_GetInsideBorder + * + * @description: + * Retrieve the @FT_StrokerBorder value corresponding to the + * `inside' borders of a given outline. + * + * @input: + * outline :: + * The source outline handle. + * + * @return: + * The border index. @FT_STROKER_BORDER_LEFT for empty or invalid + * outlines. + *} + function FT_Outline_GetInsideBorder( outline: PFT_Outline ): FT_StrokerBorder; + cdecl; external ft_lib name 'FT_Outline_GetInsideBorder'; + + + {************************************************************** + * + * @function: + * FT_Outline_GetOutsideBorder + * + * @description: + * Retrieve the @FT_StrokerBorder value corresponding to the + * `outside' borders of a given outline. + * + * @input: + * outline :: + * The source outline handle. + * + * @return: + * The border index. @FT_STROKER_BORDER_LEFT for empty or invalid + * outlines. + *} + function FT_Outline_GetOutsideBorder( outline: PFT_Outline ): FT_StrokerBorder; + cdecl; external ft_lib name 'FT_Outline_GetOutsideBorder'; + + + {************************************************************** + * + * @function: + * FT_Stroker_New + * + * @description: + * Create a new stroker object. + * + * @input: + * library :: + * FreeType library handle. + * + * @output: + * astroker :: + * A new stroker object handle. NULL in case of error. + * + * @return: + * FreeType error code. 0 means success. + *} + function FT_Stroker_New( + library_: FT_Library; + out astroker: FT_Stroker ): FT_Error; + cdecl; external ft_lib name 'FT_Stroker_New'; + + + {************************************************************** + * + * @function: + * FT_Stroker_Set + * + * @description: + * Reset a stroker object's attributes. + * + * @input: + * stroker :: + * The target stroker handle. + * + * radius :: + * The border radius. + * + * line_cap :: + * The line cap style. + * + * line_join :: + * The line join style. + * + * miter_limit :: + * The miter limit for the FT_STROKER_LINEJOIN_MITER style, + * expressed as 16.16 fixed point value. + * + * @note: + * The radius is expressed in the same units that the outline + * coordinates. + *} + procedure FT_Stroker_Set( + stroker: FT_Stroker; + radius: FT_Fixed; + line_cap: FT_Stroker_LineCap; + line_join: FT_Stroker_LineJoin; + miter_limit: FT_Fixed ); + cdecl; external ft_lib name 'FT_Stroker_Set'; + + + {************************************************************** + * + * @function: + * FT_Stroker_Rewind + * + * @description: + * Reset a stroker object without changing its attributes. + * You should call this function before beginning a new + * series of calls to @FT_Stroker_BeginSubPath or + * @FT_Stroker_EndSubPath. + * + * @input: + * stroker :: + * The target stroker handle. + *} + procedure FT_Stroker_Rewind( stroker: FT_Stroker ); + cdecl; external ft_lib name 'FT_Stroker_Rewind'; + + + {************************************************************** + * + * @function: + * FT_Stroker_ParseOutline + * + * @description: + * A convenience function used to parse a whole outline with + * the stroker. The resulting outline(s) can be retrieved + * later by functions like @FT_Stroker_GetCounts and @FT_Stroker_Export. + * + * @input: + * stroker :: + * The target stroker handle. + * + * outline :: + * The source outline. + * + * opened :: + * A boolean. If 1, the outline is treated as an open path instead + * of a closed one. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * If `opened' is 0 (the default), the outline is treated as a closed + * path, and the stroker will generate two distinct `border' outlines. + * + * If `opened' is 1, the outline is processed as an open path, and the + * stroker will generate a single `stroke' outline. + * + * This function calls @FT_Stroker_Rewind automatically. + *} + function FT_Stroker_ParseOutline( + stroker: FT_Stroker; + outline: PFT_Outline; + opened: FT_Bool): FT_Error; + cdecl; external ft_lib name 'FT_Stroker_ParseOutline'; + + + {************************************************************** + * + * @function: + * FT_Stroker_BeginSubPath + * + * @description: + * Start a new sub-path in the stroker. + * + * @input: + * stroker :: + * The target stroker handle. + * + * to :: + * A pointer to the start vector. + * + * open :: + * A boolean. If 1, the sub-path is treated as an open one. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * This function is useful when you need to stroke a path that is + * not stored as an @FT_Outline object. + *} + function FT_Stroker_BeginSubPath( + stroker: FT_Stroker; + to_: PFT_Vector; + open: FT_Bool ): FT_Error; + cdecl; external ft_lib name 'FT_Stroker_BeginSubPath'; + + + {************************************************************** + * + * @function: + * FT_Stroker_EndSubPath + * + * @description: + * Close the current sub-path in the stroker. + * + * @input: + * stroker :: + * The target stroker handle. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * You should call this function after @FT_Stroker_BeginSubPath. + * If the subpath was not `opened', this function will `draw' a + * single line segment to the start position when needed. + *} + function FT_Stroker_EndSubPath( stroker: FT_Stroker ): FT_Error; + cdecl; external ft_lib name 'FT_Stroker_EndSubPath'; + + + {************************************************************** + * + * @function: + * FT_Stroker_LineTo + * + * @description: + * `Draw' a single line segment in the stroker's current sub-path, + * from the last position. + * + * @input: + * stroker :: + * The target stroker handle. + * + * to :: + * A pointer to the destination point. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * You should call this function between @FT_Stroker_BeginSubPath and + * @FT_Stroker_EndSubPath. + *} + function FT_Stroker_LineTo( + stroker: FT_Stroker; + to_: PFT_Vector ): FT_Error; + cdecl; external ft_lib name 'FT_Stroker_LineTo'; + + + {************************************************************** + * + * @function: + * FT_Stroker_ConicTo + * + * @description: + * `Draw' a single quadratic Bézier in the stroker's current sub-path, + * from the last position. + * + * @input: + * stroker :: + * The target stroker handle. + * + * control :: + * A pointer to a Bézier control point. + * + * to :: + * A pointer to the destination point. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * You should call this function between @FT_Stroker_BeginSubPath and + * @FT_Stroker_EndSubPath. + *} + function FT_Stroker_ConicTo( + stroker: FT_Stroker; + control: PFT_Vector; + to_: PFT_Vector ): FT_Error; + cdecl; external ft_lib name 'FT_Stroker_ConicTo'; + + + {************************************************************** + * + * @function: + * FT_Stroker_CubicTo + * + * @description: + * `Draw' a single cubic Bézier in the stroker's current sub-path, + * from the last position. + * + * @input: + * stroker :: + * The target stroker handle. + * + * control1 :: + * A pointer to the first Bézier control point. + * + * control2 :: + * A pointer to second Bézier control point. + * + * to :: + * A pointer to the destination point. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * You should call this function between @FT_Stroker_BeginSubPath and + * @FT_Stroker_EndSubPath. + *} + function FT_Stroker_CubicTo( + stroker: FT_Stroker; + control1: PFT_Vector; + control2: PFT_Vector; + to_: PFT_Vector ): FT_Error; + cdecl; external ft_lib name 'FT_Stroker_CubicTo'; + + + {************************************************************** + * + * @function: + * FT_Stroker_GetBorderCounts + * + * @description: + * Call this function once you have finished parsing your paths + * with the stroker. It will return the number of points and + * contours necessary to export one of the `border' or `stroke' + * outlines generated by the stroker. + * + * @input: + * stroker :: + * The target stroker handle. + * + * border :: + * The border index. + * + * @output: + * anum_points :: + * The number of points. + * + * anum_contours :: + * The number of contours. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * When an outline, or a sub-path, is `closed', the stroker generates + * two independent `border' outlines, named `left' and `right'. + * + * When the outline, or a sub-path, is `opened', the stroker merges + * the `border' outlines with caps. The `left' border receives all + * points, while the `right' border becomes empty. + * + * Use the function @FT_Stroker_GetCounts instead if you want to + * retrieve the counts associated to both borders. + *} + function FT_Stroker_GetBorderCounts( + stroker: FT_Stroker; + border: FT_StrokerBorder; + out anum_points: FT_UInt; + out anum_contours: FT_UInt ): FT_Error; + cdecl; external ft_lib name 'FT_Stroker_GetBorderCounts'; + + + {************************************************************** + * + * @function: + * FT_Stroker_ExportBorder + * + * @description: + * Call this function after @FT_Stroker_GetBorderCounts to + * export the corresponding border to your own @FT_Outline + * structure. + * + * Note that this function will append the border points and + * contours to your outline, but will not try to resize its + * arrays. + * + * @input: + * stroker :: + * The target stroker handle. + * + * border :: + * The border index. + * + * outline :: + * The target outline handle. + * + * @note: + * Always call this function after @FT_Stroker_GetBorderCounts to + * get sure that there is enough room in your @FT_Outline object to + * receive all new data. + * + * When an outline, or a sub-path, is `closed', the stroker generates + * two independent `border' outlines, named `left' and `right' + * + * When the outline, or a sub-path, is `opened', the stroker merges + * the `border' outlines with caps. The `left' border receives all + * points, while the `right' border becomes empty. + * + * Use the function @FT_Stroker_Export instead if you want to + * retrieve all borders at once. + *} + procedure FT_Stroker_ExportBorder( + stroker: FT_Stroker; + border: FT_StrokerBorder; + outline: PFT_Outline ); + cdecl; external ft_lib name 'FT_Stroker_ExportBorder'; + + + {************************************************************** + * + * @function: + * FT_Stroker_GetCounts + * + * @description: + * Call this function once you have finished parsing your paths + * with the stroker. It returns the number of points and + * contours necessary to export all points/borders from the stroked + * outline/path. + * + * @input: + * stroker :: + * The target stroker handle. + * + * @output: + * anum_points :: + * The number of points. + * + * anum_contours :: + * The number of contours. + * + * @return: + * FreeType error code. 0 means success. + *} + function FT_Stroker_GetCounts( + stroker: FT_Stroker; + out anum_points: FT_UInt; + out anum_contours: FT_UInt ): FT_Error; + cdecl; external ft_lib name 'FT_Stroker_GetCounts'; + + + {************************************************************** + * + * @function: + * FT_Stroker_Export + * + * @description: + * Call this function after @FT_Stroker_GetBorderCounts to + * export the all borders to your own @FT_Outline structure. + * + * Note that this function will append the border points and + * contours to your outline, but will not try to resize its + * arrays. + * + * @input: + * stroker :: + * The target stroker handle. + * + * outline :: + * The target outline handle. + *} + procedure FT_Stroker_Export( + stroker: FT_Stroker; + outline: PFT_Outline ); + cdecl; external ft_lib name 'FT_Stroker_Export'; + + + {************************************************************** + * + * @function: + * FT_Stroker_Done + * + * @description: + * Destroy a stroker object. + * + * @input: + * stroker :: + * A stroker handle. Can be NULL. + *} + procedure FT_Stroker_Done( stroker: FT_Stroker ); + cdecl; external ft_lib name 'FT_Stroker_Done'; + + + {************************************************************** + * + * @function: + * FT_Glyph_Stroke + * + * @description: + * Stroke a given outline glyph object with a given stroker. + * + * @inout: + * pglyph :: + * Source glyph handle on input, new glyph handle on output. + * + * @input: + * stroker :: + * A stroker handle. + * + * destroy :: + * A Boolean. If 1, the source glyph object is destroyed + * on success. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * The source glyph is untouched in case of error. + *} + function FT_Glyph_Stroke( + var glyph: FT_Glyph; + stroker: FT_Stroker; + destroy: FT_Bool ): FT_Error; + cdecl; external ft_lib name 'FT_Glyph_Stroke'; + + + {************************************************************** + * + * @function: + * FT_Glyph_StrokeBorder + * + * @description: + * Stroke a given outline glyph object with a given stroker, but + * only return either its inside or outside border. + * + * @inout: + * pglyph :: + * Source glyph handle on input, new glyph handle on output. + * + * @input: + * stroker :: + * A stroker handle. + * + * inside :: + * A Boolean. If 1, return the inside border, otherwise + * the outside border. + * + * destroy :: + * A Boolean. If 1, the source glyph object is destroyed + * on success. + * + * @return: + * FreeType error code. 0 means success. + * + * @note: + * The source glyph is untouched in case of error. + *} + function FT_Glyph_StrokeBorder( + var glyph: FT_Glyph; + stroker: FT_Stroker; + inside: FT_Bool; + destroy: FT_Bool ): FT_Error; + cdecl; external ft_lib name 'FT_Glyph_StrokeBorder'; + +{$ENDIF TYPE_DECL} + diff --git a/cmake/src/lib/freetype/fttypes.inc b/cmake/src/lib/freetype/fttypes.inc new file mode 100644 index 00000000..a64432e6 --- /dev/null +++ b/cmake/src/lib/freetype/fttypes.inc @@ -0,0 +1,311 @@ +(***************************************************************************) +(* *) +(* fttypes.h *) +(* *) +(* FreeType simple types definitions (specification only). *) +(* *) +(* Copyright 1996-2001, 2002, 2004, 2006, 2007 by *) +(* David Turner, Robert Wilhelm, and Werner Lemberg. *) +(* *) +(* This file is part of the FreeType project, and may only be used, *) +(* modified, and distributed under the terms of the FreeType project *) +(* license, LICENSE.TXT. By continuing to use, modify, or distribute *) +(* this file you indicate that you have read the license and *) +(* understand and accept it fully. *) +(* *) +(***************************************************************************) +(***************************************************************************) +(* Pascal port by the UltraStar Deluxe Team *) +(***************************************************************************) + + (*************************************************************************) + (* *) + (* <Section> *) + (* basic_types *) + (* *) + (* <Title> *) + (* Basic Data Types *) + (* *) + (* <Abstract> *) + (* The basic data types defined by the library. *) + (* *) + (* <Description> *) + (* This section contains the basic data types defined by FreeType 2, *) + (* ranging from simple scalar types to bitmap descriptors. More *) + (* font-specific structures are defined in a different section. *) + (* *) + (* <Order> *) + (* FT_Byte *) + (* FT_Bytes *) + (* FT_Char *) + (* FT_Int *) + (* FT_UInt *) + (* FT_Short *) + (* FT_UShort *) + (* FT_Long *) + (* FT_ULong *) + (* FT_Bool *) + (* FT_Offset *) + (* FT_PtrDist *) + (* FT_String *) + (* FT_Tag *) + (* FT_Error *) + (* FT_Fixed *) + (* FT_Pointer *) + (* FT_Pos *) + (* FT_Vector *) + (* FT_BBox *) + (* FT_Matrix *) + (* FT_FWord *) + (* FT_UFWord *) + (* FT_F2Dot14 *) + (* FT_UnitVector *) + (* FT_F26Dot6 *) + (* *) + (* *) + (* FT_Generic *) + (* FT_Generic_Finalizer *) + (* *) + (* FT_Bitmap *) + (* FT_Pixel_Mode *) + (* FT_Palette_Mode *) + (* FT_Glyph_Format *) + (* FT_IMAGE_TAG *) + (* *) + (*************************************************************************) + +{$IFDEF TYPE_DECL} + + (*************************************************************************) + (* *) + (* <Type> *) + (* FT_Bool *) + (* *) + (* <Description> *) + (* A typedef of unsigned char, used for simple booleans. As usual, *) + (* values 1 and 0 represent true and false, respectively. *) + (* *) + FT_Bool = cuchar; +{$ENDIF TYPE_DECL} +{$IFNDEF TYPE_DECL} +const + FT_FALSE = 0; + FT_TRUE = 1; +{$ENDIF !TYPE_DECL} +{$IFDEF TYPE_DECL} + + (*************************************************************************) + (* *) + (* <Type> *) + (* FT_Byte *) + (* *) + (* <Description> *) + (* A simple typedef for the _unsigned_ char type. *) + (* *) + FT_Byte = cuchar; + PFT_Byte = ^FT_Byte; + + + (*************************************************************************) + (* *) + (* <Type> *) + (* FT_String *) + (* *) + (* <Description> *) + (* A simple typedef for the char type, usually used for strings. *) + (* *) + FT_String = cchar; + PFT_String = ^FT_String; + + + (*************************************************************************) + (* *) + (* <Type> *) + (* FT_Short *) + (* *) + (* <Description> *) + (* A typedef for signed short. *) + (* *) + FT_Short = csshort; + PFT_Short = ^FT_Short; + + PFT_ShortArray = ^FT_ShortArray; + FT_ShortArray = array[0 .. (MaxInt div SizeOf(FT_Short))-1] of FT_Short; + + (*************************************************************************) + (* *) + (* <Type> *) + (* FT_UShort *) + (* *) + (* <Description> *) + (* A typedef for unsigned short. *) + (* *) + FT_UShort = cushort; + + + (*************************************************************************) + (* *) + (* <Type> *) + (* FT_Int *) + (* *) + (* <Description> *) + (* A typedef for the int type. *) + (* *) + FT_Int = csint; + + + (*************************************************************************) + (* *) + (* <Type> *) + (* FT_UInt *) + (* *) + (* <Description> *) + (* A typedef for the unsigned int type. *) + (* *) + FT_UInt = cuint; + + + (*************************************************************************) + (* *) + (* <Type> *) + (* FT_Long *) + (* *) + (* <Description> *) + (* A typedef for signed long. *) + (* *) + FT_Long = cslong; + + + (*************************************************************************) + (* *) + (* <Type> *) + (* FT_ULong *) + (* *) + (* <Description> *) + (* A typedef for unsigned long. *) + (* *) + FT_ULong = culong; + + + (*************************************************************************) + (* *) + (* <Type> *) + (* FT_F26Dot6 *) + (* *) + (* <Description> *) + (* A signed 26.6 fixed float type used for vectorial pixel *) + (* coordinates. *) + (* *) + FT_F26Dot6 = cslong; + + + (*************************************************************************) + (* *) + (* <Type> *) + (* FT_Fixed *) + (* *) + (* <Description> *) + (* This type is used to store 16.16 fixed float values, like scaling *) + (* values or matrix coefficients. *) + (* *) + FT_Fixed = cslong; + + + (*************************************************************************) + (* *) + (* <Type> *) + (* FT_Error *) + (* *) + (* <Description> *) + (* The FreeType error code type. A value of 0 is always interpreted *) + (* as a successful operation. *) + (* *) + FT_Error = cint; + + + (*************************************************************************) + (* *) + (* <Struct> *) + (* FT_Matrix *) + (* *) + (* <Description> *) + (* A simple structure used to store a 2x2 matrix. Coefficients are *) + (* in 16.16 fixed float format. The computation performed is: *) + (* *) + (* { *) + (* x' = x*xx + y*xy *) + (* y' = x*yx + y*yy *) + (* } *) + (* *) + (* <Fields> *) + (* xx :: Matrix coefficient. *) + (* *) + (* xy :: Matrix coefficient. *) + (* *) + (* yx :: Matrix coefficient. *) + (* *) + (* yy :: Matrix coefficient. *) + (* *) + PFT_Matrix = ^FT_Matrix; + FT_Matrix = record + xx, xy: FT_Fixed; + yx, yy: FT_Fixed; + end; + + + (*************************************************************************) + (* *) + (* <FuncType> *) + (* FT_Generic_Finalizer *) + (* *) + (* <Description> *) + (* Describes a function used to destroy the `client' data of any *) + (* FreeType object. See the description of the FT_Generic type for *) + (* details of usage. *) + (* *) + (* <Input> *) + (* The address of the FreeType object which is under finalization. *) + (* Its client data is accessed through its `generic' field. *) + (* *) + FT_Generic_Finalizer = procedure(AnObject : pointer ); cdecl; + + + (*************************************************************************) + (* *) + (* <Struct> *) + (* FT_Generic *) + (* *) + (* <Description> *) + (* Client applications often need to associate their own data to a *) + (* variety of FreeType core objects. For example, a text layout API *) + (* might want to associate a glyph cache to a given size object. *) + (* *) + (* Most FreeType object contains a `generic' field, of type *) + (* FT_Generic, which usage is left to client applications and font *) + (* servers. *) + (* *) + (* It can be used to store a pointer to client-specific data, as well *) + (* as the address of a `finalizer' function, which will be called by *) + (* FreeType when the object is destroyed (for example, the previous *) + (* client example would put the address of the glyph cache destructor *) + (* in the `finalizer' field). *) + (* *) + (* <Fields> *) + (* data :: A typeless pointer to any client-specified data. This *) + (* field is completely ignored by the FreeType library. *) + (* *) + (* finalizer :: A pointer to a `generic finalizer' function, which *) + (* will be called when the object is destroyed. If this *) + (* field is set to NULL, no code will be called. *) + (* *) + FT_Generic = record + data: pointer; + finalizer: FT_Generic_Finalizer; + end; + + + TByteArray = array [0 .. (MaxInt div SizeOf(byte))-1] of byte; + PByteArray = ^TByteArray; + +{$ENDIF TYPE_DECL} + diff --git a/cmake/src/lib/lib-info.txt b/cmake/src/lib/lib-info.txt index 59502c7a..0a184568 100644 --- a/cmake/src/lib/lib-info.txt +++ b/cmake/src/lib/lib-info.txt @@ -1,60 +1,60 @@ -bass:
-http://www.un4seen.com/ (2.4.2.1)
-- FPC Mac OS X compatibility fixes
-
-fft:
-translation of audacity's FFT.cpp by hennymcc (maybe replace this with FFTW?)
-
-ffmpeg:
-- http://www.iversenit.dk/dev/ffmpeg-headers/: 2006-10
-- several bugs were fixed
-- many IFDEFS were added to the header to support multiple versions of ffmpeg (starting with end of 2006) and not only one specific version. This is necessary as we cannot control which version is used on linux. We could ship the ffmpeg lib with USDX and link statically but a stripped down ffmpeg is 15MB in size and takes 5 minutes to compile (so static linkage is not a good option).
-- the headers were updated to reflect the changes in the ffmpeg C-headers (http://svn.mplayerhq.hu/ffmpeg/trunk/ and http://svn.mplayerhq.hu/mplayer/trunk/libswscale/)
-
-freeimage:
-- inserted by eddie. Some compatibility fixes for platforms different than mac os x.
-- not used anymore
-
-freetype:
-- based on the AggPas (http://aggpas.org/) headers
-- just a minimal header that contains only some of the freetype functions and types. Some functions and structures/constants/types needed for USDX were added.
-- some comments added
-
-jedi-sdl:
-JEDI-SDL v1.0 Final RC 2 (http://jedi-sdl.pascalgamedevelopment.com/)
-- 64bit compatibility patch (http://sourceforge.net/tracker/index.php?func=detail&aid=1902924&group_id=43805&atid=437446)
-- some Mac OS X patches from freepascal trunk
-- some additional patched (see *.patch)
-
-midi:
-taken from http://www.torry.net/authorsmore.php?id=1615 (TMidiPlayer)
-- FPC (Win32) compatibility fixes
-- Win32 only. Maybe use some timidity stuff under linux.
-
-libpng:
-autocreated H2Pas file taken from freepascal trunk
-- bug fixes (especially H2Pas related stuff like wrong file types)
-- delphi compatibility
-- comments added
-
-portaudio:
-translation of the (patched) audacity C headers by hennymcc.
-See http://audacity.cvs.sourceforge.net/viewvc/audacity/lib-src/portaudio-v19/include/?sortdir=down
-
-portmixer:
-translation of the (patched) audacity C headers by hennymcc.
-- Unlike portaudio portmixer is part of audacity and there is no linux package for it. If we want to use it for linux, we have to link it statically. Unfortunately it requires a patched version of portaudio (which is part of audacity and statically linked to) so we have to statically link portaudio too :(.
-
-projectM:
-translation of the original C++ headers and C-wrapper by hennymcc
-
-samplerate:
-translation of the original C headers by profoX/hennymcc
-
-sqlite:
-taken from http://www.itwriting.com/blog/a-simple-delphi-wrapper-for-sqlite-3
-- slightly patched: see *.patch files for what has been patched (e.g. Binding)
-
-zlib:
-taken from freepascal (slightly patched)
+bass: +http://www.un4seen.com/ (2.4.2.1) +- FPC Mac OS X compatibility fixes + +fft: +translation of audacity's FFT.cpp by hennymcc (maybe replace this with FFTW?) + +ffmpeg: +- http://www.iversenit.dk/dev/ffmpeg-headers/: 2006-10 +- several bugs were fixed +- many IFDEFS were added to the header to support multiple versions of ffmpeg (starting with end of 2006) and not only one specific version. This is necessary as we cannot control which version is used on linux. We could ship the ffmpeg lib with USDX and link statically but a stripped down ffmpeg is 15MB in size and takes 5 minutes to compile (so static linkage is not a good option). +- the headers were updated to reflect the changes in the ffmpeg C-headers (http://svn.mplayerhq.hu/ffmpeg/trunk/ and http://svn.mplayerhq.hu/mplayer/trunk/libswscale/) + +freeimage: +- inserted by eddie. Some compatibility fixes for platforms different than mac os x. +- not used anymore + +freetype: +- based on the AggPas (http://aggpas.org/) headers +- just a minimal header that contains only some of the freetype functions and types. Some functions and structures/constants/types needed for USDX were added. +- some comments added + +jedi-sdl: +JEDI-SDL v1.0 Final RC 2 (http://jedi-sdl.pascalgamedevelopment.com/) +- 64bit compatibility patch (http://sourceforge.net/tracker/index.php?func=detail&aid=1902924&group_id=43805&atid=437446) +- some Mac OS X patches from freepascal trunk +- some additional patched (see *.patch) + +midi: +taken from http://www.torry.net/authorsmore.php?id=1615 (TMidiPlayer) +- FPC (Win32) compatibility fixes +- Win32 only. Maybe use some timidity stuff under linux. + +libpng: +autocreated H2Pas file taken from freepascal trunk +- bug fixes (especially H2Pas related stuff like wrong file types) +- delphi compatibility +- comments added + +portaudio: +translation of the (patched) audacity C headers by hennymcc. +See http://audacity.cvs.sourceforge.net/viewvc/audacity/lib-src/portaudio-v19/include/?sortdir=down + +portmixer: +translation of the (patched) audacity C headers by hennymcc. +- Unlike portaudio portmixer is part of audacity and there is no linux package for it. If we want to use it for linux, we have to link it statically. Unfortunately it requires a patched version of portaudio (which is part of audacity and statically linked to) so we have to statically link portaudio too :(. + +projectM: +translation of the original C++ headers and C-wrapper by hennymcc + +samplerate: +translation of the original C headers by profoX/hennymcc + +sqlite: +taken from http://www.itwriting.com/blog/a-simple-delphi-wrapper-for-sqlite-3 +- slightly patched: see *.patch files for what has been patched (e.g. Binding) + +zlib: +taken from freepascal (slightly patched) - delphi compatibility
\ No newline at end of file diff --git a/cmake/src/lib/midi/CIRCBUF.PAS b/cmake/src/lib/midi/CIRCBUF.PAS index 77cb3643..3ceb4c6e 100644 --- a/cmake/src/lib/midi/CIRCBUF.PAS +++ b/cmake/src/lib/midi/CIRCBUF.PAS @@ -23,7 +23,7 @@ interface {$IFDEF FPC} {$MODE Delphi} - {$H+} // use AnsiString + {$H+} // use long strings {$ENDIF} Uses diff --git a/cmake/src/lib/midi/DELPHMCB.PAS b/cmake/src/lib/midi/DELPHMCB.PAS index e607627d..ef0d5451 100644 --- a/cmake/src/lib/midi/DELPHMCB.PAS +++ b/cmake/src/lib/midi/DELPHMCB.PAS @@ -13,7 +13,7 @@ interface {$IFDEF FPC} {$MODE Delphi} - {$H+} // use AnsiString + {$H+} // use long strings {$ENDIF} uses diff --git a/cmake/src/lib/midi/MIDIDEFS.PAS b/cmake/src/lib/midi/MIDIDEFS.PAS index fc8eed26..4afe56ef 100644 --- a/cmake/src/lib/midi/MIDIDEFS.PAS +++ b/cmake/src/lib/midi/MIDIDEFS.PAS @@ -13,7 +13,7 @@ interface {$IFDEF FPC} {$MODE Delphi} - {$H+} // use AnsiString + {$H+} // use long strings {$ENDIF} uses diff --git a/cmake/src/lib/midi/MIDITYPE.PAS b/cmake/src/lib/midi/MIDITYPE.PAS index b1ec1bdd..45b50820 100644 --- a/cmake/src/lib/midi/MIDITYPE.PAS +++ b/cmake/src/lib/midi/MIDITYPE.PAS @@ -10,7 +10,7 @@ interface {$IFDEF FPC} {$MODE Delphi} - {$H+} // use AnsiString + {$H+} // use long strings {$ENDIF} uses diff --git a/cmake/src/lib/midi/MidiFile.pas b/cmake/src/lib/midi/MidiFile.pas index 11b1ca0b..acf44c04 100644 --- a/cmake/src/lib/midi/MidiFile.pas +++ b/cmake/src/lib/midi/MidiFile.pas @@ -92,18 +92,18 @@ interface {$IFDEF FPC} {$MODE Delphi} - {$H+} // use AnsiString + {$H+} // use long strings {$ENDIF} uses Windows, - //Forms, Messages, Classes, {$IFDEF FPC} WinAllocation, {$ENDIF} - SysUtils; + SysUtils, + UPath; type TChunkType = (illegal, header, track); @@ -162,7 +162,7 @@ type procedure WndProc(var Msg : TMessage); protected { Protected declarations } - midiFile: file of byte; + midiFile: TBinaryFileStream; chunkType: TChunkType; chunkLength: integer; chunkData: PByte; @@ -177,7 +177,7 @@ type FBpm: integer; FBeatsPerMeasure: integer; FusPerTick: double; - FFilename: string; + FFilename: IPath; Tracks: TList; currentTrack: TMidiTrack; @@ -191,7 +191,7 @@ type currentPos: Double; // Current Position in ticks procedure OnTrackReady; - procedure setFilename(val: string); + procedure SetFilename(val: IPath); procedure ReadChunkHeader; procedure ReadChunkContent; procedure ReadChunk; @@ -221,7 +221,7 @@ type function Ready: boolean; published { Published declarations } - property Filename: string read FFilename write setFilename; + property Filename: IPath read FFilename write SetFilename; property NumberOfTracks: integer read numberTracks; property TicksPerQuarter: integer read deltaTicks; property FileFormat: TFileFormat read FFileFormat; @@ -463,7 +463,7 @@ begin result := Tracks.Items[index]; end; -procedure TMidifile.setFilename(val: string); +procedure TMidifile.SetFilename(val: IPath); begin FFilename := val; // ReadFile; @@ -586,7 +586,7 @@ procedure TMidifile.ReadChunkHeader; var theByte: array[0..7] of byte; begin - BlockRead(midiFile, theByte, 8); + midiFile.Read(theByte[0], 8); if (theByte[0] = $4D) and (theByte[1] = $54) then begin if (theByte[2] = $68) and (theByte[3] = $64) then @@ -608,7 +608,7 @@ begin if not (chunkData = nil) then FreeMem(chunkData); GetMem(chunkData, chunkLength + 10); - BlockRead(midiFile, chunkData^, chunkLength); + midiFile.Read(chunkData^, chunkLength); chunkIndex := chunkData; chunkEnd := PByte(integer(chunkIndex) + integer(chunkLength) - 1); end; @@ -848,12 +848,10 @@ begin Tracks.Clear; chunkType := illegal; - AssignFile(midiFile, FFilename); - FileMode := 0; - Reset(midiFile); - while not eof(midiFile) do + midiFile := TBinaryFileStream.Create(FFilename, fmOpenRead); + while (midiFile.Position < midiFile.Size) do ReadChunk; - CloseFile(midiFile); + FreeAndNil(midiFile); numberTracks := Tracks.Count; end; diff --git a/cmake/src/lib/midi/MidiScope.pas b/cmake/src/lib/midi/MidiScope.pas index 42fc65fc..afc20b0f 100644 --- a/cmake/src/lib/midi/MidiScope.pas +++ b/cmake/src/lib/midi/MidiScope.pas @@ -20,7 +20,7 @@ interface {$IFDEF FPC} {$MODE Delphi} - {$H+} // use AnsiString + {$H+} // use long strings {$ENDIF} uses diff --git a/cmake/src/lib/midi/Midicons.pas b/cmake/src/lib/midi/Midicons.pas index 35dbb5f3..72259beb 100644 --- a/cmake/src/lib/midi/Midicons.pas +++ b/cmake/src/lib/midi/Midicons.pas @@ -11,7 +11,7 @@ interface {$IFDEF FPC} {$MODE Delphi} - {$H+} // use AnsiString + {$H+} // use long strings {$ENDIF} uses Messages; diff --git a/cmake/src/lib/midi/Midiin.pas b/cmake/src/lib/midi/Midiin.pas index 21db0298..a055669a 100644 --- a/cmake/src/lib/midi/Midiin.pas +++ b/cmake/src/lib/midi/Midiin.pas @@ -103,7 +103,7 @@ interface {$IFDEF FPC} {$MODE Delphi} - {$H+} // use AnsiString + {$H+} // use long strings {$ENDIF} uses @@ -237,20 +237,13 @@ uses Controls, There are special requirements and restrictions for this callback procedure (see midiInOpen in MMSYSTEM.HLP) so it's impractical to make it an object method } -{$IFDEF WIN32} +{$IFDEF MSWINDOWS} function midiHandler( hMidiIn: HMidiIn; wMsg: UINT; dwInstance: DWORD; dwParam1: DWORD; dwParam2: DWORD): Boolean; stdcall; external 'DELMID32.DLL'; -{$ELSE} -procedure midiHandler( - hMidiIn: HMidiIn; - wMsg: Word; - dwInstance: DWORD; - dwParam1: DWORD; - dwParam2: DWORD); far; external 'DELPHMID'; {$ENDIF} *) {-------------------------------------------------------------------} diff --git a/cmake/src/lib/midi/Midiout.pas b/cmake/src/lib/midi/Midiout.pas index 606d0dae..7ce385eb 100644 --- a/cmake/src/lib/midi/Midiout.pas +++ b/cmake/src/lib/midi/Midiout.pas @@ -98,7 +98,7 @@ interface {$IFDEF FPC} {$MODE Delphi} - {$H+} // use AnsiString + {$H+} // use long strings {$ENDIF} uses @@ -234,20 +234,13 @@ implementation There are special requirements and restrictions for this callback procedure (see midioutOpen in MMSYSTEM.HLP) so it's impractical to make it an object method } -{$IFDEF WIN32} +{$IFDEF MSWINDOWS} function midiHandler( hMidiIn: HMidiIn; wMsg: UINT; dwInstance: DWORD; dwParam1: DWORD; dwParam2: DWORD): Boolean; stdcall; external 'DELMID32.DLL'; -{$ELSE} -function midiHandler( - hMidiIn: HMidiIn; - wMsg: Word; - dwInstance: DWORD; - dwParam1: DWORD; - dwParam2: DWORD): Boolean; far; external 'DELPHMID.DLL'; {$ENDIF} *) diff --git a/cmake/src/lib/other/DirWatch.pas b/cmake/src/lib/other/DirWatch.pas index 9d395840..1e00ec5d 100644 --- a/cmake/src/lib/other/DirWatch.pas +++ b/cmake/src/lib/other/DirWatch.pas @@ -25,7 +25,7 @@ interface {$IFDEF FPC} {$MODE Delphi} - {$H+} // use AnsiString + {$H+} // use long strings {$ENDIF} uses diff --git a/cmake/src/lib/pcre/pcre.pas b/cmake/src/lib/pcre/pcre.pas new file mode 100644 index 00000000..50e3371a --- /dev/null +++ b/cmake/src/lib/pcre/pcre.pas @@ -0,0 +1,852 @@ +{**************************************************************************************************} +{ } +{ Project JEDI Code Library (JCL) } +{ } +{ The contents of this file are subject to the Mozilla Public License Version 1.1 (the "License"); } +{ you may not use this file except in compliance with the License. You may obtain a copy of the } +{ License at http://www.mozilla.org/MPL/ } +{ } +{ Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF } +{ ANY KIND, either express or implied. See the License for the specific language governing rights } +{ and limitations under the License. } +{ } +{ The Original Code is JclPRCE.pas. } +{ } +{ The Initial Developer of the Original Code is Peter Thornqvist. } +{ Portions created by Peter Thornqvist are Copyright (C) of Peter Thornqvist. All rights reserved. } +{ Portions created by University of Cambridge are } +{ Copyright (C) 1997-2001 by University of Cambridge. } +{ } +{ Contributor(s): } +{ Robert Rossmair (rrossmair) } +{ Mario R. Carro } +{ Florent Ouchet (outchy) } +{ } +{ The latest release of PCRE is always available from } +{ ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-xxx.tar.gz } +{ } +{**************************************************************************************************} +{ } +{ Header conversion of pcre.h } +{ } +{ } +{**************************************************************************************************} +{ } +{ Last modified: $Date:: $ } +{ Revision: $Rev:: $ } +{ Author: $Author:: $ } +{ } +{**************************************************************************************************} + +unit pcre; + +interface + +(************************************************* +* Perl-Compatible Regular Expressions * +*************************************************) + +{$IFDEF FPC} + {$MODE DELPHI} + {$PACKENUM 4} (* use 4-byte enums *) + {$PACKRECORDS C} (* C/C++-compatible record packing *) +{$ELSE} + {$MINENUMSIZE 4} (* use 4-byte enums *) +{$ENDIF} + +{$WEAKPACKAGEUNIT ON} + +(*$HPPEMIT '#include "pcre.h"'*) + +const + MAX_PATTERN_LENGTH = $10003; + {$EXTERNALSYM MAX_PATTERN_LENGTH} + MAX_QUANTIFY_REPEAT = $10000; + {$EXTERNALSYM MAX_QUANTIFY_REPEAT} + MAX_CAPTURE_COUNT = $FFFF; + {$EXTERNALSYM MAX_CAPTURE_COUNT} + MAX_NESTING_DEPTH = 200; + {$EXTERNALSYM MAX_NESTING_DEPTH} + +const + (* Options *) + PCRE_CASELESS = $00000001; + {$EXTERNALSYM PCRE_CASELESS} + PCRE_MULTILINE = $00000002; + {$EXTERNALSYM PCRE_MULTILINE} + PCRE_DOTALL = $00000004; + {$EXTERNALSYM PCRE_DOTALL} + PCRE_EXTENDED = $00000008; + {$EXTERNALSYM PCRE_EXTENDED} + PCRE_ANCHORED = $00000010; + {$EXTERNALSYM PCRE_ANCHORED} + PCRE_DOLLAR_ENDONLY = $00000020; + {$EXTERNALSYM PCRE_DOLLAR_ENDONLY} + PCRE_EXTRA = $00000040; + {$EXTERNALSYM PCRE_EXTRA} + PCRE_NOTBOL = $00000080; + {$EXTERNALSYM PCRE_NOTBOL} + PCRE_NOTEOL = $00000100; + {$EXTERNALSYM PCRE_NOTEOL} + PCRE_UNGREEDY = $00000200; + {$EXTERNALSYM PCRE_UNGREEDY} + PCRE_NOTEMPTY = $00000400; + {$EXTERNALSYM PCRE_NOTEMPTY} + PCRE_UTF8 = $00000800; + {$EXTERNALSYM PCRE_UTF8} + PCRE_NO_AUTO_CAPTURE = $00001000; + {$EXTERNALSYM PCRE_NO_AUTO_CAPTURE} + PCRE_NO_UTF8_CHECK = $00002000; + {$EXTERNALSYM PCRE_NO_UTF8_CHECK} + PCRE_AUTO_CALLOUT = $00004000; + {$EXTERNALSYM PCRE_AUTO_CALLOUT} + PCRE_PARTIAL_SOFT = $00008000; + {$EXTERNALSYM PCRE_PARTIAL_SOFT} + PCRE_PARTIAL = PCRE_PARTIAL_SOFT; // Backwards compatible synonym + {$EXTERNALSYM PCRE_PARTIAL} + PCRE_DFA_SHORTEST = $00010000; + {$EXTERNALSYM PCRE_DFA_SHORTEST} + PCRE_DFA_RESTART = $00020000; + {$EXTERNALSYM PCRE_DFA_RESTART} + PCRE_FIRSTLINE = $00040000; + {$EXTERNALSYM PCRE_FIRSTLINE} + PCRE_DUPNAMES = $00080000; + {$EXTERNALSYM PCRE_DUPNAMES} + PCRE_NEWLINE_CR = $00100000; + {$EXTERNALSYM PCRE_NEWLINE_CR} + PCRE_NEWLINE_LF = $00200000; + {$EXTERNALSYM PCRE_NEWLINE_LF} + PCRE_NEWLINE_CRLF = $00300000; + {$EXTERNALSYM PCRE_NEWLINE_CRLF} + PCRE_NEWLINE_ANY = $00400000; + {$EXTERNALSYM PCRE_NEWLINE_ANY} + PCRE_NEWLINE_ANYCRLF = $00500000; + {$EXTERNALSYM PCRE_NEWLINE_ANYCRLF} + PCRE_BSR_ANYCRLF = $00800000; + {$EXTERNALSYM PCRE_BSR_ANYCRLF} + PCRE_BSR_UNICODE = $01000000; + {$EXTERNALSYM PCRE_BSR_UNICODE} + PCRE_JAVASCRIPT_COMPAT = $02000000; + {$EXTERNALSYM PCRE_JAVASCRIPT_COMPAT} + PCRE_NO_START_OPTIMIZE = $04000000; + {$EXTERNALSYM PCRE_NO_START_OPTIMIZE} + PCRE_NO_START_OPTIMISE = $04000000; + {$EXTERNALSYM PCRE_NO_START_OPTIMISE} + PCRE_PARTIAL_HARD = $08000000; + {$EXTERNALSYM PCRE_PARTIAL_HARD} + PCRE_NOTEMPTY_ATSTART = $10000000; + {$EXTERNALSYM PCRE_NOTEMPTY_ATSTART} + + (* Exec-time and get-time error codes *) + + PCRE_ERROR_NOMATCH = -1; + {$EXTERNALSYM PCRE_ERROR_NOMATCH} + PCRE_ERROR_NULL = -2; + {$EXTERNALSYM PCRE_ERROR_NULL} + PCRE_ERROR_BADOPTION = -3; + {$EXTERNALSYM PCRE_ERROR_BADOPTION} + PCRE_ERROR_BADMAGIC = -4; + {$EXTERNALSYM PCRE_ERROR_BADMAGIC} + PCRE_ERROR_UNKNOWN_NODE = -5; + {$EXTERNALSYM PCRE_ERROR_UNKNOWN_NODE} + PCRE_ERROR_NOMEMORY = -6; + {$EXTERNALSYM PCRE_ERROR_NOMEMORY} + PCRE_ERROR_NOSUBSTRING = -7; + {$EXTERNALSYM PCRE_ERROR_NOSUBSTRING} + PCRE_ERROR_MATCHLIMIT = -8; + {$EXTERNALSYM PCRE_ERROR_MATCHLIMIT} + PCRE_ERROR_CALLOUT = -9; (* Never used by PCRE itself *) + {$EXTERNALSYM PCRE_ERROR_CALLOUT} + PCRE_ERROR_BADUTF8 = -10; + {$EXTERNALSYM PCRE_ERROR_BADUTF8} + PCRE_ERROR_BADUTF8_OFFSET = -11; + {$EXTERNALSYM PCRE_ERROR_BADUTF8_OFFSET} + PCRE_ERROR_PARTIAL = -12; + {$EXTERNALSYM PCRE_ERROR_PARTIAL} + PCRE_ERROR_BADPARTIAL = -13; + {$EXTERNALSYM PCRE_ERROR_BADPARTIAL} + PCRE_ERROR_INTERNAL = -14; + {$EXTERNALSYM PCRE_ERROR_INTERNAL} + PCRE_ERROR_BADCOUNT = -15; + {$EXTERNALSYM PCRE_ERROR_BADCOUNT} + PCRE_ERROR_DFA_UITEM = -16; + {$EXTERNALSYM PCRE_ERROR_DFA_UITEM} + PCRE_ERROR_DFA_UCOND = -17; + {$EXTERNALSYM PCRE_ERROR_DFA_UCOND} + PCRE_ERROR_DFA_UMLIMIT = -18; + {$EXTERNALSYM PCRE_ERROR_DFA_UMLIMIT} + PCRE_ERROR_DFA_WSSIZE = -19; + {$EXTERNALSYM PCRE_ERROR_DFA_WSSIZE} + PCRE_ERROR_DFA_RECURSE = -20; + {$EXTERNALSYM PCRE_ERROR_DFA_RECURSE} + PCRE_ERROR_RECURSIONLIMIT = -21; + {$EXTERNALSYM PCRE_ERROR_RECURSIONLIMIT} + PCRE_ERROR_NULLWSLIMIT = -22; (* No longer actually used *) + {$EXTERNALSYM PCRE_ERROR_NULLWSLIMIT} + PCRE_ERROR_BADNEWLINE = -23; + {$EXTERNALSYM PCRE_ERROR_BADNEWLINE} + + (* Request types for pcre_fullinfo() *) + + PCRE_INFO_OPTIONS = 0; + {$EXTERNALSYM PCRE_INFO_OPTIONS} + PCRE_INFO_SIZE = 1; + {$EXTERNALSYM PCRE_INFO_SIZE} + PCRE_INFO_CAPTURECOUNT = 2; + {$EXTERNALSYM PCRE_INFO_CAPTURECOUNT} + PCRE_INFO_BACKREFMAX = 3; + {$EXTERNALSYM PCRE_INFO_BACKREFMAX} + PCRE_INFO_FIRSTCHAR = 4; + {$EXTERNALSYM PCRE_INFO_FIRSTCHAR} + PCRE_INFO_FIRSTTABLE = 5; + {$EXTERNALSYM PCRE_INFO_FIRSTTABLE} + PCRE_INFO_LASTLITERAL = 6; + {$EXTERNALSYM PCRE_INFO_LASTLITERAL} + PCRE_INFO_NAMEENTRYSIZE = 7; + {$EXTERNALSYM PCRE_INFO_NAMEENTRYSIZE} + PCRE_INFO_NAMECOUNT = 8; + {$EXTERNALSYM PCRE_INFO_NAMECOUNT} + PCRE_INFO_NAMETABLE = 9; + {$EXTERNALSYM PCRE_INFO_NAMETABLE} + PCRE_INFO_STUDYSIZE = 10; + {$EXTERNALSYM PCRE_INFO_STUDYSIZE} + PCRE_INFO_DEFAULT_TABLES = 11; + {$EXTERNALSYM PCRE_INFO_DEFAULT_TABLES} + PCRE_INFO_OKPARTIAL = 12; + {$EXTERNALSYM PCRE_INFO_OKPARTIAL} + PCRE_INFO_JCHANGED = 13; + {$EXTERNALSYM PCRE_INFO_JCHANGED} + PCRE_INFO_HASCRORLF = 14; + {$EXTERNALSYM PCRE_INFO_HASCRORLF} + PCRE_INFO_MINLENGTH = 15; + {$EXTERNALSYM PCRE_INFO_MINLENGTH} + + (* Request types for pcre_config() *) + PCRE_CONFIG_UTF8 = 0; + {$EXTERNALSYM PCRE_CONFIG_UTF8} + PCRE_CONFIG_NEWLINE = 1; + {$EXTERNALSYM PCRE_CONFIG_NEWLINE} + PCRE_CONFIG_LINK_SIZE = 2; + {$EXTERNALSYM PCRE_CONFIG_LINK_SIZE} + PCRE_CONFIG_POSIX_MALLOC_THRESHOLD = 3; + {$EXTERNALSYM PCRE_CONFIG_POSIX_MALLOC_THRESHOLD} + PCRE_CONFIG_MATCH_LIMIT = 4; + {$EXTERNALSYM PCRE_CONFIG_MATCH_LIMIT} + PCRE_CONFIG_STACKRECURSE = 5; + {$EXTERNALSYM PCRE_CONFIG_STACKRECURSE} + PCRE_CONFIG_UNICODE_PROPERTIES = 6; + {$EXTERNALSYM PCRE_CONFIG_UNICODE_PROPERTIES} + PCRE_CONFIG_MATCH_LIMIT_RECURSION = 7; + {$EXTERNALSYM PCRE_CONFIG_MATCH_LIMIT_RECURSION} + PCRE_CONFIG_BSR = 8; + {$EXTERNALSYM PCRE_CONFIG_BSR} + + (* Bit flags for the pcre_extra structure *) + + PCRE_EXTRA_STUDY_DATA = $0001; + {$EXTERNALSYM PCRE_EXTRA_STUDY_DATA} + PCRE_EXTRA_MATCH_LIMIT = $0002; + {$EXTERNALSYM PCRE_EXTRA_MATCH_LIMIT} + PCRE_EXTRA_CALLOUT_DATA = $0004; + {$EXTERNALSYM PCRE_EXTRA_CALLOUT_DATA} + PCRE_EXTRA_TABLES = $0008; + {$EXTERNALSYM PCRE_EXTRA_TABLES} + PCRE_EXTRA_MATCH_LIMIT_RECURSION = $0010; + {$EXTERNALSYM PCRE_EXTRA_MATCH_LIMIT_RECURSION} + +type + {$IFNDEF FPC} + {$IFDEF CPU64} + SizeInt = Int64; + {$ELSE ~CPU64} + SizeInt = Integer; + {$ENDIF ~CPU64} + PPAnsiChar = ^PAnsiChar; + {$ENDIF ~FPC} + PPPAnsiChar = ^PPAnsiChar; + + real_pcre = packed record + {magic_number: Longword; + size: Integer; + tables: PAnsiChar; + options: Longword; + top_bracket: Word; + top_backref: word; + first_char: PAnsiChar; + req_char: PAnsiChar; + code: array [0..0] of AnsiChar;} + end; + TPCRE = real_pcre; + PPCRE = ^TPCRE; + + real_pcre_extra = packed record + {options: PAnsiChar; + start_bits: array [0..31] of AnsiChar;} + flags: Cardinal; (* Bits for which fields are set *) + study_data: Pointer; (* Opaque data from pcre_study() *) + match_limit: Cardinal; (* Maximum number of calls to match() *) + callout_data: Pointer; (* Data passed back in callouts *) + tables: PAnsiChar; (* Pointer to character tables *) + match_limit_recursion: Cardinal; (* Max recursive calls to match() *) + end; + TPCREExtra = real_pcre_extra; + PPCREExtra = ^TPCREExtra; + + pcre_callout_block = packed record + version: Integer; (* Identifies version of block *) + (* ------------------------ Version 0 ------------------------------- *) + callout_number: Integer; (* Number compiled into pattern *) + offset_vector: PInteger; (* The offset vector *) + subject: PAnsiChar; (* The subject being matched *) + subject_length: Integer; (* The length of the subject *) + start_match: Integer; (* Offset to start of this match attempt *) + current_position: Integer; (* Where we currently are in the subject *) + capture_top: Integer; (* Max current capture *) + capture_last: Integer; (* Most recently closed capture *) + callout_data: Pointer; (* Data passed in with the call *) + (* ------------------- Added for Version 1 -------------------------- *) + pattern_position: Integer; (* Offset to next item in the pattern *) + next_item_length: Integer; (* Length of next item in the pattern *) + (* ------------------------------------------------------------------ *) + end; + + pcre_malloc_callback = function(Size: SizeInt): Pointer; cdecl; + {$EXTERNALSYM pcre_malloc_callback} + pcre_free_callback = procedure(P: Pointer); cdecl; + {$EXTERNALSYM pcre_free_callback} + pcre_stack_malloc_callback = function(Size: SizeInt): Pointer; cdecl; + {$EXTERNALSYM pcre_stack_malloc_callback} + pcre_stack_free_callback = procedure(P: Pointer); cdecl; + {$EXTERNALSYM pcre_stack_free_callback} + pcre_callout_callback = function(var callout_block: pcre_callout_block): Integer; cdecl; + {$EXTERNALSYM pcre_callout_callback} + +var + // renamed from "pcre_X" to "pcre_X_func" to allow functions with name "pcre_X" to be + // declared in implementation when static linked + pcre_malloc_func: ^pcre_malloc_callback = nil; + {$EXTERNALSYM pcre_malloc_func} + pcre_free_func: ^pcre_free_callback = nil; + {$EXTERNALSYM pcre_free_func} + pcre_stack_malloc_func: ^pcre_stack_malloc_callback = nil; + {$EXTERNALSYM pcre_stack_malloc_func} + pcre_stack_free_func: ^pcre_stack_free_callback = nil; + {$EXTERNALSYM pcre_stack_free_func} + pcre_callout_func: ^pcre_callout_callback = nil; + {$EXTERNALSYM pcre_callout_func} + +procedure SetPCREMallocCallback(const Value: pcre_malloc_callback); +{$EXTERNALSYM SetPCREMallocCallback} +function GetPCREMallocCallback: pcre_malloc_callback; +{$EXTERNALSYM GetPCREMallocCallback} +function CallPCREMalloc(Size: SizeInt): Pointer; +{$EXTERNALSYM CallPCREMalloc} + +procedure SetPCREFreeCallback(const Value: pcre_free_callback); +{$EXTERNALSYM SetPCREFreeCallback} +function GetPCREFreeCallback: pcre_free_callback; +{$EXTERNALSYM GetPCREFreeCallback} +procedure CallPCREFree(P: Pointer); +{$EXTERNALSYM CallPCREFree} + +procedure SetPCREStackMallocCallback(const Value: pcre_stack_malloc_callback); +{$EXTERNALSYM SetPCREStackMallocCallback} +function GetPCREStackMallocCallback: pcre_stack_malloc_callback; +{$EXTERNALSYM GetPCREStackMallocCallback} +function CallPCREStackMalloc(Size: SizeInt): Pointer; +{$EXTERNALSYM CallPCREStackMalloc} + +procedure SetPCREStackFreeCallback(const Value: pcre_stack_free_callback); +{$EXTERNALSYM SetPCREStackFreeCallback} +function GetPCREStackFreeCallback: pcre_stack_free_callback; +{$EXTERNALSYM GetPCREStackFreeCallback} +procedure CallPCREStackFree(P: Pointer); +{$EXTERNALSYM CallPCREStackFree} + +procedure SetPCRECalloutCallback(const Value: pcre_callout_callback); +{$EXTERNALSYM SetPCRECalloutCallback} +function GetPCRECalloutCallback: pcre_callout_callback; +{$EXTERNALSYM GetPCRECalloutCallback} +function CallPCRECallout(var callout_block: pcre_callout_block): Integer; +{$EXTERNALSYM CallPCRECallout} + +type + TPCRELibNotLoadedHandler = procedure; cdecl; + +var + // Value to initialize function pointers below with, in case LoadPCRE fails + // or UnloadPCRE is called. Typically the handler will raise an exception. + LibNotLoadedHandler: TPCRELibNotLoadedHandler = nil; + +(* Functions *) + +// dynamic dll import +type + pcre_compile_func = function(const pattern: PAnsiChar; options: Integer; + const errptr: PPAnsiChar; erroffset: PInteger; const tableptr: PAnsiChar): PPCRE; + cdecl; + {$EXTERNALSYM pcre_compile_func} + pcre_compile2_func = function(const pattern: PAnsiChar; options: Integer; + const errorcodeptr: PInteger; const errorptr: PPAnsiChar; erroroffset: PInteger; + const tables: PAnsiChar): PPCRE; cdecl; + {$EXTERNALSYM pcre_compile2_func} + pcre_config_func = function(what: Integer; where: Pointer): Integer; + cdecl; + {$EXTERNALSYM pcre_config_func} + pcre_copy_named_substring_func = function(const code: PPCRE; const subject: PAnsiChar; + ovector: PInteger; stringcount: Integer; const stringname: PAnsiChar; + buffer: PAnsiChar; size: Integer): Integer; cdecl; + {$EXTERNALSYM pcre_copy_named_substring_func} + pcre_copy_substring_func = function(const subject: PAnsiChar; ovector: PInteger; + stringcount, stringnumber: Integer; buffer: PAnsiChar; buffersize: Integer): Integer; + cdecl; + {$EXTERNALSYM pcre_copy_substring_func} + pcre_dfa_exec_func = function(const argument_re: PPCRE; const extra_data: PPCREExtra; + const subject: PAnsiChar; length: Integer; start_offset: Integer; + options: Integer; offsets: PInteger; offsetcount: Integer; workspace: PInteger; + wscount: Integer): Integer; cdecl; + {$EXTERNALSYM pcre_dfa_exec_func} + pcre_exec_func = function(const code: PPCRE; const extra: PPCREExtra; const subject: PAnsiChar; + length, startoffset, options: Integer; ovector: PInteger; ovecsize: Integer): Integer; + cdecl; + {$EXTERNALSYM pcre_exec_func} + pcre_free_substring_func = procedure(stringptr: PAnsiChar); + cdecl; + {$EXTERNALSYM pcre_free_substring_func} + pcre_free_substring_list_func = procedure(stringptr: PPAnsiChar); + cdecl; + {$EXTERNALSYM pcre_free_substring_list_func} + pcre_fullinfo_func = function(const code: PPCRE; const extra: PPCREExtra; + what: Integer; where: Pointer): Integer; + cdecl; + {$EXTERNALSYM pcre_fullinfo_func} + pcre_get_named_substring_func = function(const code: PPCRE; const subject: PAnsiChar; + ovector: PInteger; stringcount: Integer; const stringname: PAnsiChar; + const stringptr: PPAnsiChar): Integer; cdecl; + {$EXTERNALSYM pcre_get_named_substring_func} + pcre_get_stringnumber_func = function(const code: PPCRE; + const stringname: PAnsiChar): Integer; cdecl; + {$EXTERNALSYM pcre_get_stringnumber_func} + pcre_get_stringtable_entries_func = function(const code: PPCRE; const stringname: PAnsiChar; + firstptr: PPAnsiChar; lastptr: PPAnsiChar): Integer; + cdecl; + {$EXTERNALSYM pcre_get_stringtable_entries_func} + pcre_get_substring_func = function(const subject: PAnsiChar; ovector: PInteger; + stringcount, stringnumber: Integer; const stringptr: PPAnsiChar): Integer; + cdecl; + {$EXTERNALSYM pcre_get_substring_func} + pcre_get_substring_list_func = function(const subject: PAnsiChar; ovector: PInteger; + stringcount: Integer; listptr: PPPAnsiChar): Integer; + cdecl; + {$EXTERNALSYM pcre_get_substring_list_func} + pcre_info_func = function(const code: PPCRE; optptr, firstcharptr: PInteger): Integer; + cdecl; + {$EXTERNALSYM pcre_info_func} + pcre_maketables_func = function: PAnsiChar; cdecl; + {$EXTERNALSYM pcre_maketables_func} + pcre_refcount_func = function(argument_re: PPCRE; adjust: Integer): Integer; + cdecl; + {$EXTERNALSYM pcre_refcount_func} + pcre_study_func = function(const code: PPCRE; options: Integer; const errptr: PPAnsiChar): PPCREExtra; + cdecl; + {$EXTERNALSYM pcre_study_func} + pcre_version_func = function: PAnsiChar; cdecl; + {$EXTERNALSYM pcre_version_func} + +var + pcre_compile: pcre_compile_func = nil; + {$EXTERNALSYM pcre_compile} + pcre_compile2: pcre_compile2_func = nil; + {$EXTERNALSYM pcre_compile2} + pcre_config: pcre_config_func = nil; + {$EXTERNALSYM pcre_config} + pcre_copy_named_substring: pcre_copy_named_substring_func = nil; + {$EXTERNALSYM pcre_copy_named_substring} + pcre_copy_substring: pcre_copy_substring_func = nil; + {$EXTERNALSYM pcre_copy_substring} + pcre_dfa_exec: pcre_dfa_exec_func = nil; + {$EXTERNALSYM pcre_dfa_exec} + pcre_exec: pcre_exec_func = nil; + {$EXTERNALSYM pcre_exec} + pcre_free_substring: pcre_free_substring_func = nil; + {$EXTERNALSYM pcre_free_substring} + pcre_free_substring_list: pcre_free_substring_list_func = nil; + {$EXTERNALSYM pcre_free_substring_list} + pcre_fullinfo: pcre_fullinfo_func = nil; + {$EXTERNALSYM pcre_fullinfo} + pcre_get_named_substring: pcre_get_named_substring_func = nil; + {$EXTERNALSYM pcre_get_named_substring} + pcre_get_stringnumber: pcre_get_stringnumber_func = nil; + {$EXTERNALSYM pcre_get_stringnumber} + pcre_get_stringtable_entries: pcre_get_stringtable_entries_func = nil; + {$EXTERNALSYM pcre_get_stringtable_entries} + pcre_get_substring: pcre_get_substring_func = nil; + {$EXTERNALSYM pcre_get_substring} + pcre_get_substring_list: pcre_get_substring_list_func = nil; + {$EXTERNALSYM pcre_get_substring_list} + pcre_info: pcre_info_func = nil; + {$EXTERNALSYM pcre_info} + pcre_maketables: pcre_maketables_func = nil; + {$EXTERNALSYM pcre_maketables} + pcre_refcount: pcre_refcount_func = nil; + {$EXTERNALSYM pcre_refcount} + pcre_study: pcre_study_func = nil; + {$EXTERNALSYM pcre_study} + pcre_version: pcre_version_func = nil; + {$EXTERNALSYM pcre_version} + +function IsPCRELoaded: Boolean; +function LoadPCRE: Boolean; +procedure UnloadPCRE; + +implementation + +uses + SysUtils, + {$IFDEF MSWINDOWS} + Windows; + {$ENDIF MSWINDOWS} + {$IFDEF UNIX} + {$IFDEF HAS_UNIT_TYPES} + Types, + {$ENDIF HAS_UNIT_TYPES} + {$IFDEF HAS_UNIT_LIBC} + Libc; + {$ELSE ~HAS_UNIT_LIBC} + dl; + {$ENDIF ~HAS_UNIT_LIBC} + {$ENDIF UNIX} + +type + {$IFDEF MSWINDOWS} + TModuleHandle = HINST; + {$ENDIF MSWINDOWS} + {$IFDEF LINUX} + TModuleHandle = Pointer; + {$ENDIF LINUX} + {$IFDEF DARWIN} + TModuleHandle = Pointer; + {$ENDIF DARWIN} + +const + {$IFDEF MSWINDOWS} + libpcremodulename = 'pcre3.dll'; + {$ENDIF MSWINDOWS} + {$IFDEF LINUX} + libpcremodulename = 'libpcre.so.0'; + {$ENDIF LINUX} + {$IFDEF DARWIN} + libpcremodulename = 'libpcre.dylib'; + {$ENDIF DARWIN} + PCRECompileExportName = 'pcre_compile'; + PCRECompile2ExportName = 'pcre_compile2'; + PCREConfigExportName = 'pcre_config'; + PCRECopyNamedSubstringExportName = 'pcre_copy_named_substring'; + PCRECopySubStringExportName = 'pcre_copy_substring'; + PCREDfaExecExportName = 'pcre_dfa_exec'; + PCREExecExportName = 'pcre_exec'; + PCREFreeSubStringExportName = 'pcre_free_substring'; + PCREFreeSubStringListExportName = 'pcre_free_substring_list'; + PCREFullInfoExportName = 'pcre_fullinfo'; + PCREGetNamedSubstringExportName = 'pcre_get_named_substring'; + PCREGetStringNumberExportName = 'pcre_get_stringnumber'; + PCREGetStringTableEntriesExportName = 'pcre_get_stringtable_entries'; + PCREGetSubStringExportName = 'pcre_get_substring'; + PCREGetSubStringListExportName = 'pcre_get_substring_list'; + PCREInfoExportName = 'pcre_info'; + PCREMakeTablesExportName = 'pcre_maketables'; + PCRERefCountExportName = 'pcre_refcount'; + PCREStudyExportName = 'pcre_study'; + PCREVersionExportName = 'pcre_version'; + PCREMallocExportName = 'pcre_malloc'; + PCREFreeExportName = 'pcre_free'; + PCREStackMallocExportName = 'pcre_stack_malloc'; + PCREStackFreeExportName = 'pcre_stack_free'; + PCRECalloutExportName = 'pcre_callout'; + INVALID_MODULEHANDLE_VALUE = TModuleHandle(0); + +var + PCRELib: TModuleHandle = INVALID_MODULEHANDLE_VALUE; + +procedure SetPCREMallocCallback(const Value: pcre_malloc_callback); +begin + if not Assigned(pcre_malloc_func) then + LoadPCRE; + + if Assigned(pcre_malloc_func) then + pcre_malloc_func^ := Value + else if Assigned(LibNotLoadedHandler) then + LibNotLoadedHandler; +end; + +function GetPCREMallocCallback: pcre_malloc_callback; +begin + if not Assigned(pcre_malloc_func) then + LoadPCRE; + + if not Assigned(pcre_malloc_func) then + begin + Result := nil; + if Assigned(LibNotLoadedHandler) then + LibNotLoadedHandler; + end + else + Result := pcre_malloc_func^; +end; + +function CallPCREMalloc(Size: SizeInt): Pointer; +begin + Result := pcre_malloc_func^(Size); +end; + +procedure SetPCREFreeCallback(const Value: pcre_free_callback); +begin + if not Assigned(pcre_free_func) then + LoadPCRE; + + if Assigned(pcre_free_func) then + pcre_free_func^ := Value + else if Assigned(LibNotLoadedHandler) then + LibNotLoadedHandler; +end; + +function GetPCREFreeCallback: pcre_free_callback; +begin + if not Assigned(pcre_free_func) then + LoadPCRE; + + if not Assigned(pcre_free_func) then + begin + Result := nil; + if Assigned(LibNotLoadedHandler) then + LibNotLoadedHandler; + end + else + Result := pcre_free_func^ +end; + +procedure CallPCREFree(P: Pointer); +begin + pcre_free_func^(P); +end; + +procedure SetPCREStackMallocCallback(const Value: pcre_stack_malloc_callback); +begin + if not Assigned(pcre_stack_malloc_func) then + LoadPCRE; + + if Assigned(pcre_stack_malloc_func) then + pcre_stack_malloc_func^ := Value + else if Assigned(LibNotLoadedHandler) then + LibNotLoadedHandler; +end; + +function GetPCREStackMallocCallback: pcre_stack_malloc_callback; +begin + if not Assigned(pcre_stack_malloc_func) then + LoadPCRE; + + if not Assigned(pcre_stack_malloc_func) then + begin + Result := nil; + if Assigned(LibNotLoadedHandler) then + LibNotLoadedHandler; + end + else + Result := pcre_stack_malloc_func^; +end; + +function CallPCREStackMalloc(Size: SizeInt): Pointer; +begin + Result := pcre_stack_malloc_func^(Size); +end; + +procedure SetPCREStackFreeCallback(const Value: pcre_stack_free_callback); +begin + if not Assigned(pcre_stack_free_func) then + LoadPCRE; + + if Assigned(pcre_stack_free_func) then + pcre_stack_free_func^ := Value + else if Assigned(LibNotLoadedHandler) then + LibNotLoadedHandler; +end; + +function GetPCREStackFreeCallback: pcre_stack_free_callback; +begin + if not Assigned(pcre_stack_free_func) then + LoadPCRE; + + if not Assigned(pcre_stack_free_func) then + begin + Result := nil; + if Assigned(LibNotLoadedHandler) then + LibNotLoadedHandler; + end + else + Result := pcre_stack_free_func^; +end; + +procedure CallPCREStackFree(P: Pointer); +begin + pcre_stack_free_func^(P); +end; + +procedure SetPCRECalloutCallback(const Value: pcre_callout_callback); +begin + if not Assigned(pcre_callout_func) then + LoadPCRE; + + if Assigned(pcre_callout_func) then + pcre_callout_func^ := Value + else if Assigned(LibNotLoadedHandler) then + LibNotLoadedHandler; +end; + +function GetPCRECalloutCallback: pcre_callout_callback; +begin + if not Assigned(pcre_callout_func) then + LoadPCRE; + + if not Assigned(pcre_callout_func) then + begin + Result := nil; + if Assigned(LibNotLoadedHandler) then + LibNotLoadedHandler; + end + else + Result := pcre_callout_func^; +end; + +function CallPCRECallout(var callout_block: pcre_callout_block): Integer; +begin + Result := pcre_callout_func^(callout_block); +end; + +procedure InitPCREFuncPtrs(const Value: Pointer); +begin + @pcre_compile := Value; + @pcre_compile2 := Value; + @pcre_config := Value; + @pcre_copy_named_substring := Value; + @pcre_copy_substring := Value; + @pcre_dfa_exec := Value; + @pcre_exec := Value; + @pcre_free_substring := Value; + @pcre_free_substring_list := Value; + @pcre_fullinfo := Value; + @pcre_get_named_substring := Value; + @pcre_get_stringnumber := Value; + @pcre_get_stringtable_entries := Value; + @pcre_get_substring := Value; + @pcre_get_substring_list := Value; + @pcre_info := Value; + @pcre_maketables := Value; + @pcre_refcount := Value; + @pcre_study := Value; + @pcre_version := Value; + pcre_malloc_func := nil; + pcre_free_func := nil; + pcre_stack_malloc_func := nil; + pcre_stack_free_func := nil; + pcre_callout_func := nil; +end; + +function IsPCRELoaded: Boolean; +begin + Result := PCRELib <> INVALID_MODULEHANDLE_VALUE; +end; + +function LoadPCRE: Boolean; + function GetSymbol(SymbolName: PAnsiChar): Pointer; + begin + {$IFDEF MSWINDOWS} + Result := GetProcAddress(PCRELib, SymbolName); + {$ENDIF MSWINDOWS} + {$IFDEF UNIX} + Result := dlsym(PCRELib, SymbolName); + {$ENDIF UNIX} + end; + +begin + Result := PCRELib <> INVALID_MODULEHANDLE_VALUE; + if Result then + Exit; + + if PCRELib = INVALID_MODULEHANDLE_VALUE then + {$IFDEF MSWINDOWS} + PCRELib := SafeLoadLibrary(libpcremodulename); + {$ENDIF MSWINDOWS} + {$IFDEF UNIX} + PCRELib := dlopen(PAnsiChar(libpcremodulename), RTLD_NOW); + {$ENDIF UNIX} + Result := PCRELib <> INVALID_MODULEHANDLE_VALUE; + if Result then + begin + @pcre_compile := GetSymbol(PCRECompileExportName); + @pcre_compile2 := GetSymbol(PCRECompile2ExportName); + @pcre_config := GetSymbol(PCREConfigExportName); + @pcre_copy_named_substring := GetSymbol(PCRECopyNamedSubstringExportName); + @pcre_copy_substring := GetSymbol(PCRECopySubStringExportName); + @pcre_dfa_exec := GetSymbol(PCREDfaExecExportName); + @pcre_exec := GetSymbol(PCREExecExportName); + @pcre_free_substring := GetSymbol(PCREFreeSubStringExportName); + @pcre_free_substring_list := GetSymbol(PCREFreeSubStringListExportName); + @pcre_fullinfo := GetSymbol(PCREFullInfoExportName); + @pcre_get_named_substring := GetSymbol(PCREGetNamedSubstringExportName); + @pcre_get_stringnumber := GetSymbol(PCREGetStringNumberExportName); + @pcre_get_stringtable_entries := GetSymbol(PCREGetStringTableEntriesExportName); + @pcre_get_substring := GetSymbol(PCREGetSubStringExportName); + @pcre_get_substring_list := GetSymbol(PCREGetSubStringListExportName); + @pcre_info := GetSymbol(PCREInfoExportName); + @pcre_maketables := GetSymbol(PCREMakeTablesExportName); + @pcre_refcount := GetSymbol(PCRERefCountExportName); + @pcre_study := GetSymbol(PCREStudyExportName); + @pcre_version := GetSymbol(PCREVersionExportName); + pcre_malloc_func := GetSymbol(PCREMallocExportName); + pcre_free_func := GetSymbol(PCREFreeExportName); + pcre_stack_malloc_func := GetSymbol(PCREStackMallocExportName); + pcre_stack_free_func := GetSymbol(PCREStackFreeExportName); + pcre_callout_func := GetSymbol(PCRECalloutExportName); + end + else + InitPCREFuncPtrs(@LibNotLoadedHandler); +end; + +procedure UnloadPCRE; +begin + if PCRELib <> INVALID_MODULEHANDLE_VALUE then + {$IFDEF MSWINDOWS} + FreeLibrary(PCRELib); + {$ENDIF MSWINDOWS} + {$IFDEF UNIX} + dlclose(Pointer(PCRELib)); + {$ENDIF UNIX} + PCRELib := INVALID_MODULEHANDLE_VALUE; + InitPCREFuncPtrs(@LibNotLoadedHandler); +end; + +(* +function pcre_compile; external libpcremodulename name PCRECompileExportName; +function pcre_compile2; external libpcremodulename name PCRECompile2ExportName; +function pcre_config; external libpcremodulename name PCREConfigExportName; +function pcre_copy_named_substring; external libpcremodulename name PCRECopyNamedSubStringExportName; +function pcre_copy_substring; external libpcremodulename name PCRECopySubStringExportName; +function pcre_dfa_exec; external libpcremodulename name PCREDfaExecExportName; +function pcre_exec; external libpcremodulename name PCREExecExportName; +procedure pcre_free_substring; external libpcremodulename name PCREFreeSubStringExportName; +procedure pcre_free_substring_list; external libpcremodulename name PCREFreeSubStringListExportName; +function pcre_fullinfo; external libpcremodulename name PCREFullInfoExportName; +function pcre_get_named_substring; external libpcremodulename name PCREGetNamedSubStringExportName; +function pcre_get_stringnumber; external libpcremodulename name PCREGetStringNumberExportName; +function pcre_get_stringtable_entries; external libpcremodulename name PCREGetStringTableEntriesExportName; +function pcre_get_substring; external libpcremodulename name PCREGetSubStringExportName; +function pcre_get_substring_list; external libpcremodulename name PCREGetSubStringListExportName; +function pcre_info; external libpcremodulename name PCREInfoExportName; +function pcre_maketables; external libpcremodulename name PCREMakeTablesExportName; +function pcre_refcount; external libpcremodulename name PCRERefCountExportName; +function pcre_study; external libpcremodulename name PCREStudyExportName; +function pcre_version; external libpcremodulename name PCREVersionExportName; +*) + +end. diff --git a/cmake/src/lib/portaudio/portaudio.pas b/cmake/src/lib/portaudio/portaudio.pas index a0286b48..ea7d06b7 100644 --- a/cmake/src/lib/portaudio/portaudio.pas +++ b/cmake/src/lib/portaudio/portaudio.pas @@ -109,8 +109,8 @@ type TPaErrorCode = {enum}cint; const paStreamIsNotStopped = (paNotInitialized+18); paInputOverflowed = (paNotInitialized+19); paOutputUnderflowed = (paNotInitialized+20); - paHostApiNotFound = (paNotInitialized+21); - paInvalidHostApi = (paNotInitialized+22); + paHostApiNotFound = (paNotInitialized+21); // The notes below are from the + paInvalidHostApi = (paNotInitialized+22); // original file portaudio.h paCanNotReadFromACallbackStream = (paNotInitialized+23); {**< @todo review error code name *} paCanNotWriteToACallbackStream = (paNotInitialized+24); {**< @todo review error code name *} paCanNotReadFromAnOutputOnlyStream = (paNotInitialized+25); {**< @todo review error code name *} diff --git a/cmake/src/lib/projectM/cwrapper/projectM-cwrapper.h b/cmake/src/lib/projectM/cwrapper/projectM-cwrapper.h index 43f36ef4..125b1253 100644 --- a/cmake/src/lib/projectM/cwrapper/projectM-cwrapper.h +++ b/cmake/src/lib/projectM/cwrapper/projectM-cwrapper.h @@ -7,10 +7,11 @@ #define PROJECTM_VERSION_1_00_00 1000000 // 1.00.00 = 1.0 or 1.01 (same version number for 1.0 and 1.01) #define PROJECTM_VERSION_1_10_00 1010000 // 1.10.00 = 1.1 (bigger than 1.2 due to strange versioning) #define PROJECTM_VERSION_1_02_00 1002000 // 1.02.00 = 1.2 +#define PROJECTM_VERSION_2_00_00 2000000 // 2.00.00 = 2.0 // version of projectM to wrap (see PROJECTM_VERSION) #ifndef PROJECTM_VERSION_INT -#define PROJECTM_VERSION_INT PROJECTM_VERSION_1_02_00 +#define PROJECTM_VERSION_INT PROJECTM_VERSION_2_00_00 #endif extern "C" { diff --git a/cmake/src/lib/projectM/projectM.pas b/cmake/src/lib/projectM/projectM.pas index 4adba17d..533cb19b 100644 --- a/cmake/src/lib/projectM/projectM.pas +++ b/cmake/src/lib/projectM/projectM.pas @@ -2,7 +2,7 @@ unit projectM; {$IFDEF FPC} {$MODE DELPHI} - {$H+} (* use AnsiString *) + {$H+} (* use long strings *) {$PACKENUM 4} (* use 4-byte enums *) {$PACKRECORDS C} (* C/C++-compatible record packing *) {$ELSE} diff --git a/cmake/src/lib/zlib/zlib.pas b/cmake/src/lib/zlib/zlib.pas index 31d6a68b..8d09313f 100644 --- a/cmake/src/lib/zlib/zlib.pas +++ b/cmake/src/lib/zlib/zlib.pas @@ -14,7 +14,7 @@ interface {$ifdef FPC} {$mode objfpc} // Needed for array of const - {$H+} // use AnsiString + {$H+} // use long strings {$PACKRECORDS C} {$endif} |