|
|
@@ -3,8 +3,396 @@ library libTextSuite; |
|
|
|
{$mode objfpc}{$H+} |
|
|
|
|
|
|
|
uses |
|
|
|
Classes; |
|
|
|
Classes, SysUtils, |
|
|
|
utsTextSuite, utsTypes, utsRendererOpenGL, utsRendererOpenGLES, |
|
|
|
uutlGenerics; |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
//external types and contstants///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
type |
|
|
|
{$Z4} |
|
|
|
TltsErrorCode = ( |
|
|
|
ltsErrUnknown = -1, |
|
|
|
ltsErrNone = 0, |
|
|
|
|
|
|
|
// misc |
|
|
|
ltsErrNotInitialized = 1, |
|
|
|
ltsErrInvalidEnum = 2, |
|
|
|
ltsErrInvalidValue = 3, |
|
|
|
ltsErrInvalidOperation = 4, |
|
|
|
|
|
|
|
// invalid handles |
|
|
|
ltsErrInvalidContextHandle = 100, |
|
|
|
ltsErrInvalidRendererHandle = 101 |
|
|
|
); |
|
|
|
|
|
|
|
{$Z4} |
|
|
|
TltsRendererType = ( |
|
|
|
ltsRendererOpenGL, |
|
|
|
ltsRendererOpenGLES, |
|
|
|
ltsRendererCustom |
|
|
|
); |
|
|
|
|
|
|
|
TltsContextHandle = Pointer; |
|
|
|
TltsRendererHandle = Pointer; |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
//internal types and contstants///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
TltsContext = class(TtsContext) |
|
|
|
public |
|
|
|
destructor Destroy; override; |
|
|
|
end; |
|
|
|
TtsContextHashSet = specialize TutlHashSet<TtsContext>; |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
TltsRendererOpenGL = class(TtsRendererOpenGL) |
|
|
|
public |
|
|
|
// TODO destructor Destroy; override; |
|
|
|
end; |
|
|
|
|
|
|
|
TltsRendererOpenGLES = class(TtsRendererOpenGLES) |
|
|
|
public |
|
|
|
// TODO destructor Destroy; override; |
|
|
|
end; |
|
|
|
|
|
|
|
{ TODO |
|
|
|
TltsRendererCustom = class(TtsRenderer) |
|
|
|
protected |
|
|
|
function CreateRenderRef(const aChar: TtsChar; const aCharImage: TtsImage): TtsCharRenderRef; override; |
|
|
|
procedure FreeRenderRef(const aCharRef: TtsCharRenderRef); override; |
|
|
|
|
|
|
|
procedure BeginRender; override; |
|
|
|
procedure EndRender; override; |
|
|
|
|
|
|
|
procedure SetDrawPos(const X, Y: Integer); override; |
|
|
|
function GetDrawPos: TtsPosition; override; |
|
|
|
procedure MoveDrawPos(const X, Y: Integer); override; |
|
|
|
procedure SetColor(const aColor: TtsColor4f); override; |
|
|
|
procedure Render(const aCharRef: TtsCharRenderRef; const aForcedWidth: Integer = 0); override; |
|
|
|
public |
|
|
|
// TODO destructor Destroy; override; |
|
|
|
end; |
|
|
|
} |
|
|
|
|
|
|
|
TtsRendererHashSet = specialize TutlHashSet<TtsRenderer>; |
|
|
|
|
|
|
|
var |
|
|
|
IsInitilized: Boolean = false; |
|
|
|
Contexts: TtsContextHashSet = nil; |
|
|
|
Renderers: TtsRendererHashSet = nil; |
|
|
|
LastErrorCode: TltsErrorCode = ltsErrNone; |
|
|
|
LastErrorMsg: String; |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
//helper methods//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
procedure SetLastError(const aEx: Exception); |
|
|
|
begin |
|
|
|
LastErrorCode := ltsErrUnknown; |
|
|
|
LastErrorMsg := aEx.Message; |
|
|
|
end; |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
procedure SetLastError(const aErrorCode: TltsErrorCode; const aErrorMsg: String); |
|
|
|
begin |
|
|
|
LastErrorCode := aErrorCode; |
|
|
|
LastErrorMsg := aErrorMsg; |
|
|
|
end; |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
function CheckIfInitialized: Boolean; |
|
|
|
begin |
|
|
|
result := IsInitilized; |
|
|
|
if not result then |
|
|
|
SetLastError(ltsErrNotInitialized, 'libTextSuite has not been initialized. call ltsInitialize before using any other methods.'); |
|
|
|
end; |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
function CheckContextHandle(const aHandle: TltsContextHandle; out aContext: TtsContext): Boolean; |
|
|
|
begin |
|
|
|
result := CheckIfInitialized; |
|
|
|
if result then begin |
|
|
|
aContext := TltsContext(aHandle); |
|
|
|
result := Contexts.Contains(aContext); |
|
|
|
if not result then |
|
|
|
SetLastError(ltsErrInvalidContextHandle, Format('0x%.16x is not a valid context handle', [{%H-}PtrUInt(aHandle)])); |
|
|
|
end; |
|
|
|
end; |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
function CheckRendererHandle(const aHandle: TltsContextHandle; out aRenderer: TtsRenderer): Boolean; |
|
|
|
begin |
|
|
|
result := CheckIfInitialized; |
|
|
|
if result then begin |
|
|
|
aRenderer := TtsRenderer(aHandle); |
|
|
|
result := Renderers.Contains(aRenderer); |
|
|
|
if not result then |
|
|
|
SetLastError(ltsErrInvalidRendererHandle, Format('0x%.16x is not a valid renderer handle', [{%H-}PtrUInt(aHandle)])); |
|
|
|
end; |
|
|
|
end; |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
function ValidateCodePage(const aValue: TtsCodePage): Boolean; |
|
|
|
begin |
|
|
|
result := (aValue >= Low(TtsCodePage)) and (aValue <= High(TtsCodePage)); |
|
|
|
end; |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
function ValidateFormat(const aValue: TtsFormat): Boolean; |
|
|
|
begin |
|
|
|
result := (aValue >= Low(TtsFormat)) and (aValue <= High(TtsFormat)); |
|
|
|
end; |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
//Context/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
function ltsContextCreate: TltsContextHandle; stdcall; |
|
|
|
var |
|
|
|
c: TltsContext; |
|
|
|
begin |
|
|
|
try |
|
|
|
result := nil; |
|
|
|
if not CheckIfInitialized then |
|
|
|
exit; |
|
|
|
c := TltsContext.Create; |
|
|
|
Contexts.Add(c); |
|
|
|
result := c; |
|
|
|
except |
|
|
|
on ex: Exception do begin |
|
|
|
SetLastError(ex); |
|
|
|
result := nil; |
|
|
|
end; |
|
|
|
end; |
|
|
|
end; |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
function ltsContextGetCodePage(const aHandle: TltsContextHandle; var aCodePage: TtsCodePage): TltsErrorCode; stdcall; |
|
|
|
var |
|
|
|
c: TtsContext; |
|
|
|
begin |
|
|
|
try |
|
|
|
result := ltsErrNone; |
|
|
|
if CheckContextHandle(aHandle, c) |
|
|
|
then aCodePage := c.CodePage |
|
|
|
else result := LastErrorCode; |
|
|
|
except |
|
|
|
on ex: Exception do begin |
|
|
|
SetLastError(ex); |
|
|
|
result := LastErrorCode; |
|
|
|
end; |
|
|
|
end; |
|
|
|
end; |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
function ltsContextGetDefaultChar(const aHandle: TltsContextHandle; var aValue: WideChar): TltsErrorCode; stdcall; |
|
|
|
var |
|
|
|
c: TtsContext; |
|
|
|
begin |
|
|
|
try |
|
|
|
result := ltsErrNone; |
|
|
|
if CheckContextHandle(aHandle, c) |
|
|
|
then aValue := c.CodePageDefault |
|
|
|
else result := LastErrorCode; |
|
|
|
except |
|
|
|
on ex: Exception do begin |
|
|
|
SetLastError(ex); |
|
|
|
result := LastErrorCode; |
|
|
|
end; |
|
|
|
end; |
|
|
|
end; |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
function ltsContextSetCodePage(const aHandle: TltsContextHandle; const aCodePage: TtsCodePage): TltsErrorCode; stdcall; |
|
|
|
var |
|
|
|
c: TtsContext; |
|
|
|
begin |
|
|
|
try |
|
|
|
result := ltsErrNone; |
|
|
|
if CheckContextHandle(aHandle, c) then begin |
|
|
|
if not ValidateCodePage(aCodePage) then begin |
|
|
|
SetLastError(ltsErrInvalidEnum, Format('%d is not a valid enum value for CodePage', [aCodePage])); |
|
|
|
result := LastErrorCode; |
|
|
|
end else |
|
|
|
c.CodePage := aCodePage; |
|
|
|
end else |
|
|
|
result := LastErrorCode; |
|
|
|
except |
|
|
|
on ex: Exception do begin |
|
|
|
SetLastError(ex); |
|
|
|
result := LastErrorCode; |
|
|
|
end; |
|
|
|
end; |
|
|
|
end; |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
function ltsContextSetDefaultChar(const aHandle: TltsContextHandle; const aValue: WideChar): TltsErrorCode; stdcall; |
|
|
|
var |
|
|
|
c: TtsContext; |
|
|
|
begin |
|
|
|
try |
|
|
|
result := ltsErrNone; |
|
|
|
if CheckContextHandle(aHandle, c) |
|
|
|
then c.CodePageDefault := aValue |
|
|
|
else result := LastErrorCode; |
|
|
|
except |
|
|
|
on ex: Exception do begin |
|
|
|
SetLastError(ex); |
|
|
|
result := LastErrorCode; |
|
|
|
end; |
|
|
|
end; |
|
|
|
end; |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
function ltsContextDestroy(const aHandle: TltsContextHandle): TltsErrorCode; stdcall; |
|
|
|
var |
|
|
|
c: TtsContext; |
|
|
|
begin |
|
|
|
try |
|
|
|
result := ltsErrNone; |
|
|
|
if CheckContextHandle(aHandle, c) |
|
|
|
then Contexts.Remove(c) |
|
|
|
else result := LastErrorCode; |
|
|
|
except |
|
|
|
on ex: Exception do begin |
|
|
|
SetLastError(ex); |
|
|
|
result := LastErrorCode; |
|
|
|
end; |
|
|
|
end; |
|
|
|
end; |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
//Renderer////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
function ltsRendererCreate(const aHandle: TltsContextHandle; const aType: TltsRendererType; const aFormat: TtsFormat): TltsRendererHandle; stdcall; |
|
|
|
var |
|
|
|
c: TtsContext; |
|
|
|
r: TtsRenderer; |
|
|
|
begin |
|
|
|
try |
|
|
|
result := nil; |
|
|
|
if not CheckContextHandle(aHandle, c) then |
|
|
|
exit; |
|
|
|
|
|
|
|
if not ValidateFormat(aFormat) then begin |
|
|
|
SetLastError(ltsErrInvalidEnum, Format('%d is not a valid format', [aFormat])); |
|
|
|
exit; |
|
|
|
end; |
|
|
|
|
|
|
|
case aType of |
|
|
|
ltsRendererOpenGL: r := TltsRendererOpenGL.Create(c, aFormat); |
|
|
|
ltsRendererOpenGLES: r := TltsRendererOpenGLES.Create(c, aFormat); |
|
|
|
// TODO ltsRendererCustom: r := TltsRendererCustom.Create(c, aFormat); |
|
|
|
else |
|
|
|
SetLastError(ltsErrInvalidEnum, Format('%d is not a valid renderer type', [aType])); |
|
|
|
exit; |
|
|
|
end; |
|
|
|
Renderers.Add(r); |
|
|
|
result := r; |
|
|
|
except |
|
|
|
on ex: Exception do begin |
|
|
|
SetLastError(ex); |
|
|
|
result := nil; |
|
|
|
end; |
|
|
|
end; |
|
|
|
end; |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
function ltsRendererDestroy(const aHandle: TltsRendererHandle): TltsErrorCode; stdcall; |
|
|
|
var |
|
|
|
r: TtsRenderer; |
|
|
|
begin |
|
|
|
try |
|
|
|
result := ltsErrNone; |
|
|
|
if CheckRendererHandle(aHandle, r) |
|
|
|
then Renderers.Remove(r) |
|
|
|
else result := LastErrorCode; |
|
|
|
except |
|
|
|
on ex: Exception do begin |
|
|
|
SetLastError(ex); |
|
|
|
result := LastErrorCode; |
|
|
|
end; |
|
|
|
end; |
|
|
|
end; |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
//Global//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
function ltsInitialize: TltsErrorCode; stdcall; |
|
|
|
begin |
|
|
|
try |
|
|
|
Contexts := TtsContextHashSet.Create(true); |
|
|
|
Renderers := TtsRendererHashSet.Create(true); |
|
|
|
IsInitilized := true; |
|
|
|
result := ltsErrNone; |
|
|
|
except |
|
|
|
on ex: Exception do begin |
|
|
|
SetLastError(ex); |
|
|
|
result := LastErrorCode; |
|
|
|
end; |
|
|
|
end; |
|
|
|
end; |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
function ltsGetLastErrorCode: TltsErrorCode; stdcall; |
|
|
|
begin |
|
|
|
result := LastErrorCode; |
|
|
|
end; |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
function ltsGetLastErrorMsg: PAnsiChar; stdcall; |
|
|
|
begin |
|
|
|
result := PAnsiChar(LastErrorMsg); |
|
|
|
end; |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
function ltsFinalize: TltsErrorCode; stdcall; |
|
|
|
begin |
|
|
|
try |
|
|
|
IsInitilized := false; |
|
|
|
FreeAndNil(Renderers); |
|
|
|
FreeAndNil(Contexts); |
|
|
|
result := ltsErrNone; |
|
|
|
except |
|
|
|
on ex: Exception do begin |
|
|
|
SetLastError(ex); |
|
|
|
result := LastErrorCode; |
|
|
|
end; |
|
|
|
end; |
|
|
|
end; |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
exports |
|
|
|
ltsContextCreate, |
|
|
|
ltsContextGetCodePage, |
|
|
|
ltsContextGetDefaultChar, |
|
|
|
ltsContextSetCodePage, |
|
|
|
ltsContextSetDefaultChar, |
|
|
|
ltsContextDestroy, |
|
|
|
|
|
|
|
ltsRendererCreate, |
|
|
|
ltsRendererDestroy, |
|
|
|
|
|
|
|
ltsInitialize, |
|
|
|
ltsGetLastErrorCode, |
|
|
|
ltsGetLastErrorMsg, |
|
|
|
ltsFinalize; |
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
//TltsContext/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// |
|
|
|
destructor TltsContext.Destroy; |
|
|
|
var |
|
|
|
i: Integer; |
|
|
|
begin |
|
|
|
if Assigned(Renderers) then begin |
|
|
|
for i := fRenderers.Count-1 downto 0 do |
|
|
|
Renderers.Remove(fRenderers[i] as TtsRenderer); |
|
|
|
end; |
|
|
|
// TODO cleanup generators |
|
|
|
inherited Destroy; |
|
|
|
end; |
|
|
|
|
|
|
|
end. |
|
|
|
|