diff --git a/TextSuite b/TextSuite
index 4145843..a5f9cf1 160000
--- a/TextSuite
+++ b/TextSuite
@@ -1 +1 @@
-Subproject commit 414584359b16746bee43cf52d661ee6112ee824b
+Subproject commit a5f9cf19e54f765078e9490a6d678b5b3f87a3dc
diff --git a/header/ulibTextSuite.pas b/header/ulibTextSuite.pas
index b833b57..601b931 100644
--- a/header/ulibTextSuite.pas
+++ b/header/ulibTextSuite.pas
@@ -7,7 +7,7 @@ unit ulibTextSuite;
interface
uses
- Classes, SysUtils;
+ Classes, SysUtils, contnrs;
type
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -51,8 +51,7 @@ type
TltsRendererType = (
ltsRendererUnknown,
ltsRendererOpenGL,
- ltsRendererOpenGLES,
- ltsRendererCustom
+ ltsRendererOpenGLES
);
{$Z4}
@@ -253,6 +252,7 @@ type
TltsFontHandle = TltsHandle;
TltsPostProcessorHandle = TltsHandle;
TltsImageHandle = TltsHandle;
+ TltsCharHandle = TltsHandle;
TltsStreamOrigin = (
ltsStreamOriginBegin = Integer(soBeginning),
@@ -269,6 +269,38 @@ type
seek: TltsStreamFuncSeek;
end;
+ TltsPostProcessorExecuteFunc = procedure(const aCharHandle: TltsCharHandle; const aImageHandle: TltsImageHandle; aArgs: Pointer);
+ PltsPostProcessorCustomData = ^TltsPostProcessorCustomData;
+ TltsPostProcessorCustomData = packed record
+ args: Pointer;
+ execute: TltsPostProcessorExecuteFunc;
+ end;
+
+ TltsRendererCustomBeginRender = procedure(aArgs: Pointer); stdcall;
+ TltsRendererCustomEndRender = procedure(aArgs: Pointer); stdcall;
+ TltsRendererCustomGetDrawPos = function (aArgs: Pointer): TltsPosition; stdcall;
+ TltsRendererCustomSetDrawPos = procedure(const aValue: TltsPosition; aArgs: Pointer); stdcall;
+ TltsRendererCustomMoveDrawPos = procedure(const aOffset: TltsPosition; aArgs: Pointer); stdcall;
+ TltsRendererCustomSetColor = procedure(const aValue: TltsColor4f; aArgs: Pointer); stdcall;
+ TltsRendererCustomRender = procedure(const aRef: Pointer; const aForcedWidth: Integer; aArgs: Pointer); stdcall;
+ TltsRendererCustomCreateRef = function (const aChar: TltsCharHandle; const aImage: TltsImageHandle; aArgs: Pointer): Pointer; stdcall;
+ TltsRendererCustomFreeRef = procedure(const aRef: Pointer; aArgs: Pointer); stdcall;
+ PltsRendererCustomData = ^TltsRendererCustomData;
+ TltsRendererCustomData = packed record
+ args: Pointer;
+
+ BeginRender: TltsRendererCustomBeginRender;
+ EndRender: TltsRendererCustomEndRender;
+ GetDrawPos: TltsRendererCustomGetDrawPos;
+ SetDrawPos: TltsRendererCustomSetDrawPos;
+ MoveDrawPos: TltsRendererCustomMoveDrawPos;
+ SetColor: TltsRendererCustomSetColor;
+ Render: TltsRendererCustomRender;
+
+ CreatRef: TltsRendererCustomCreateRef;
+ FreeRef: TltsRendererCustomFreeRef;
+ end;
+
TltsImage = class;
TltsImageLoadFunc = procedure(const aImage: TltsImage; X, Y: Integer; var aPixel: TltsColor4f; aArgs: Pointer);
TltsImageBlendFunc = function (const aSrc, aDst: TltsColor4f; aArgs: Pointer): TltsColor4f;
@@ -285,6 +317,7 @@ type
TltsContextDestroy = function(const aHandle: TltsContextHandle): TltsErrorCode; stdcall;
TltsRendererCreate = function(const aHandle: TltsContextHandle; const aType: TltsRendererType; const aFormat: TltsFormat): TltsRendererHandle; stdcall;
+ TltsRendererCustomCreate = function(const aHandle: TltsContextHandle; const aFormat: TltsFormat; const aData: PltsRendererCustomData): TltsRendererHandle; stdcall;
TltsRendererBeginBlock = function(const aHandle: TltsRendererHandle; const aTop, aLeft, aWidth, aHeight: Integer; const aFlags: TltsBlockFlags): TltsTextBlockHandle; stdcall;
TltsRendererEndBlock = function(const aHandle: TltsRendererHandle; const aBlock: TltsTextBlockHandle): TltsErrorCode; stdcall;
TltsRendererAbortBlock = function(const aHandle: TltsRendererHandle; const aBlock: TltsTextBlockHandle): TltsErrorCode; stdcall;
@@ -362,12 +395,18 @@ type
TltsPostProcessorAddRange = function(const aHandle: TltsPostProcessorHandle; const aUsage: TltsCharRangeUsage; const aStart, aStop: WideChar): TltsErrorCode; stdcall;
TltsPostProcessorAddChars = function(const aHandle: TltsPostProcessorHandle; const aUsage: TltsCharRangeUsage; const aChars: PWideChar): TltsErrorCode; stdcall;
TltsPostProcessorClearRanges = function(const aHandle: TltsPostProcessorHandle): TltsErrorCode; stdcall;
+ TltsPostProcessorExecute = function (const aHandle: TltsPostProcessorHandle; const aChar: TltsCharHandle; const aImage: TltsImageHandle): TltsErrorCode; stdcall;
TltsPostProcessorFillColorCreate = function(const aContext: TltsContextHandle; const aColor: TltsColor4f; const aModes: TltsImageModes; const aChannels: TltsColorChannels): TltsPostProcessorHandle; stdcall;
TltsPostProcessorFillPatterCreate = function(const aContext: TltsContextHandle; const aPattern: TltsImageHandle; const aOwnsPatter: Boolean; const aPosition: TltsPosition; const aModes: TltsImageModes; const aChannels: TltsColorChannels): TltsPostProcessorHandle; stdcall;
TltsPostProcessorBorderCreate = function(const aContext: TltsContextHandle; const aWidth, aStrength: Single; const aColor: TltsColor4f; const aKeepSize: Boolean): TltsPostProcessorHandle; stdcall;
TltsPostProcessorShadowCreate = function(const aContext: TltsContextHandle; const aRadius, aStrength: Single; const aOffset: TltsPosition; const aColor: TltsColor4f): TltsPostProcessorHandle; stdcall;
+ TltsPostProcessorCustomCreate = function(const aContext: TltsContextHandle; const aData: PltsPostProcessorCustomData): TltsPostProcessorHandle; stdcall;
TltsPostProcessorDestroy = function(const aHandle: TltsPostProcessorHandle): TltsErrorCode; stdcall;
+ TltsCharGetCharCode = function(const aHandle: TltsCharHandle; out aValue: WideChar): TltsErrorCode; stdcall;
+ TltsCharGetGlyphMetric = function(const aHandle: TltsCharHandle; out aValue: TltsGlyphMetric): TltsErrorCode; stdcall;
+ TltsCharSetGlyphMetric = function(const aHandle: TltsCharHandle; const aValue: TltsGlyphMetric): TltsErrorCode; stdcall;
+
TltsInitialize = function(): TltsErrorCode; stdcall;
TltsGetLastErrorCode = function(): TltsErrorCode; stdcall;
TltsGetLastErrorMsg = function(): PAnsiChar; stdcall;
@@ -383,6 +422,7 @@ var
ltsContextDestroy: TltsContextDestroy;
ltsRendererCreate: TltsRendererCreate;
+ ltsRendererCustomCreate: TltsRendererCustomCreate;
ltsRendererBeginBlock: TltsRendererBeginBlock;
ltsRendererEndBlock: TltsRendererEndBlock;
ltsRendererAbortBlock: TltsRendererAbortBlock;
@@ -460,12 +500,18 @@ var
ltsPostProcessorAddRange: TltsPostProcessorAddRange;
ltsPostProcessorAddChars: TltsPostProcessorAddChars;
ltsPostProcessorClearRanges: TltsPostProcessorClearRanges;
+ ltsPostProcessorExecute: TltsPostProcessorExecute;
ltsPostProcessorFillColorCreate: TltsPostProcessorFillColorCreate;
ltsPostProcessorFillPatterCreate: TltsPostProcessorFillPatterCreate;
ltsPostProcessorBorderCreate: TltsPostProcessorBorderCreate;
ltsPostProcessorShadowCreate: TltsPostProcessorShadowCreate;
+ ltsPostProcessorCustomCreate: TltsPostProcessorCustomCreate;
ltsPostProcessorDestroy: TltsPostProcessorDestroy;
+ ltsCharGetCharCode: TltsCharGetCharCode;
+ ltsCharGetGlyphMetric: TltsCharGetGlyphMetric;
+ ltsCharSetGlyphMetric: TltsCharSetGlyphMetric;
+
ltsGetLastErrorCode: TltsGetLastErrorCode;
ltsGetLastErrorMsg: TltsGetLastErrorMsg;
@@ -607,40 +653,12 @@ type
destructor Destroy; override;
end;
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- TltsRenderer = class(TObject)
- private
- fHandle: TltsRendererHandle;
- public
- property Handle: TltsRendererHandle read fHandle;
-
- function BeginBlock(const aTop, aLeft, aWidth, aHeight: Integer; const aFlags: TltsBlockFlags): TltsTextBlock;
- procedure EndBlock(var aTextBlock: TltsTextBlock);
- procedure AbortBlock(var aTextBlock: TltsTextBlock);
-
- function GetTextWidthA(const aFont: TltsFont; const aText: PAnsiChar): Integer;
- function GetTextWidthW(const aFont: TltsFont; const aText: PWideChar): Integer;
-
- constructor Create(const aHandle: TltsRendererHandle);
- destructor Destroy; override;
- end;
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- TltsRendererOpenGL = class(TltsRenderer)
- public
- constructor Create(const aContext: TltsContext; const aFormat: TltsFormat);
- end;
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
- TltsRendererOpenGLES = class(TltsRenderer)
- public
- constructor Create(const aContext: TltsContext; const aFormat: TltsFormat);
- end;
-
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TltsImage = class(TObject)
private
fHandle: TltsImageHandle;
+ fOwnsHandle: Boolean;
+
function GetData: Pointer;
function GetDataSize: Integer;
function GetFormat: TltsFormat;
@@ -674,14 +692,82 @@ type
procedure Blend(const aImage: TltsImage; const X, Y: Integer; const aFunc: TltsImageBlendFunc; aArgs: Pointer);
procedure Blur(const aHorzRad, aHorzStr, aVertRad, aVertStr: Single; const aMask: TltsColorChannels);
+ constructor Create(const aHandle: TltsImageHandle);
constructor Create(const aContext: TltsContext);
destructor Destroy; override;
end;
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TltsChar = class(TObject)
+ private
+ fHandle: TltsCharHandle;
+ function GetCharCode: WideChar;
+ function GetGlyphMetric: TltsGlyphMetric;
+ procedure SetGlyphMetric(aValue: TltsGlyphMetric);
+ public
+ property Handle: TltsCharHandle read fHandle;
+ property CharCode: WideChar read GetCharCode;
+ property GlyphMetric: TltsGlyphMetric read GetGlyphMetric write SetGlyphMetric;
+
+ constructor Create(const aHandle: TltsCharHandle);
+ end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TltsRenderer = class(TObject)
+ private
+ fHandle: TltsRendererHandle;
+ public
+ property Handle: TltsRendererHandle read fHandle;
+
+ function BeginBlock(const aTop, aLeft, aWidth, aHeight: Integer; const aFlags: TltsBlockFlags): TltsTextBlock;
+ procedure EndBlock(var aTextBlock: TltsTextBlock);
+ procedure AbortBlock(var aTextBlock: TltsTextBlock);
+
+ function GetTextWidthA(const aFont: TltsFont; const aText: PAnsiChar): Integer;
+ function GetTextWidthW(const aFont: TltsFont; const aText: PWideChar): Integer;
+
+ constructor Create(const aHandle: TltsRendererHandle);
+ destructor Destroy; override;
+ end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TltsRendererOpenGL = class(TltsRenderer)
+ public
+ constructor Create(const aContext: TltsContext; const aFormat: TltsFormat);
+ end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TltsRendererOpenGLES = class(TltsRenderer)
+ public
+ constructor Create(const aContext: TltsContext; const aFormat: TltsFormat);
+ end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TltsRendererCustom = class(TltsRenderer)
+ protected
+ fDrawPos: TltsPosition;
+ fColor: TltsColor4f;
+
+ procedure BeginRender; virtual;
+ procedure EndRender; virtual;
+ function GetDrawPos: TltsPosition; virtual;
+ procedure SetDrawPos(const aValue: TltsPosition); virtual;
+ procedure MoveDrawPos(const aOffset: TltsPosition); virtual;
+ procedure SetColor(const aValue: TltsColor4f); virtual;
+ procedure Render(const aRenderRef: Pointer; const aForcedWidth: Integer = 0); virtual;
+ protected
+ function CreateRenderRef(const aChar: TltsChar; const aImage: TltsImage): Pointer; virtual;
+ procedure FreeRenderRef(const aRenderRef: Pointer); virtual;
+ public
+ constructor Create(const aContext: TltsContext; const aFormat: TltsFormat);
+ end;
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TltsPostProcessor = class(TObject)
private
fHandle: TltsPostProcessorHandle;
+ protected
+ procedure Execute(const aChar: TltsChar; const aImage: TltsImage); virtual;
public
property Handle: TltsPostProcessorHandle read fHandle;
@@ -758,6 +844,43 @@ type
constructor Create(const aContext: TltsContext; const aRadius, aStrength: Single; const aOffset: TltsPosition; const aColor: TltsColor4f);
end;
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TltsPostProcessorCustom = class(TltsPostProcessor)
+ public
+ constructor Create(const aContext: TltsContext);
+ end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TltsPostProcessorList = class(TltsPostProcessorCustom)
+ private
+ fItems: TObjectList;
+
+ function GetCount: Integer;
+ function GetItem(const aIndex: Integer): TltsPostProcessor;
+ function GetOwnsObjects: Boolean;
+
+ procedure SetOwnsObjects(aValue: Boolean);
+
+ protected
+ procedure Execute(const aChar: TltsChar; const aImage: TltsImage); override;
+
+ public
+ property Count: Integer read GetCount;
+ property OwnsObjects: Boolean read GetOwnsObjects write SetOwnsObjects;
+
+ property Items[const aIndex: Integer]: TltsPostProcessor read GetItem;
+
+ procedure Add(const aPostProcessor: TltsPostProcessor);
+ procedure Delete(const aIndex: Integer);
+ procedure Clear;
+
+ function Remove(const aPostProcessor: TltsPostProcessor): Integer;
+ function IndexOf(const aPostProcessor: TltsPostProcessor): Integer;
+
+ constructor Create(const aContext: TltsContext; const aOwnsObjects: Boolean);
+ destructor Destroy; override;
+ end;
+
implementation
{$IF DEFINED(WIN32) OR DEFINED(WIN64)}
@@ -916,6 +1039,7 @@ begin
ltsContextDestroy := TltsContextDestroy( LoadProc('ltsContextDestroy'));
ltsRendererCreate := TltsRendererCreate( LoadProc('ltsRendererCreate'));
+ ltsRendererCustomCreate := TltsRendererCustomCreate( LoadProc('ltsRendererCustomCreate'));
ltsRendererBeginBlock := TltsRendererBeginBlock( LoadProc('ltsRendererBeginBlock'));
ltsRendererEndBlock := TltsRendererEndBlock( LoadProc('ltsRendererEndBlock'));
ltsRendererAbortBlock := TltsRendererAbortBlock( LoadProc('ltsRendererAbortBlock'));
@@ -992,12 +1116,18 @@ begin
ltsPostProcessorAddRange := TltsPostProcessorAddRange( LoadProc('ltsPostProcessorAddRange'));
ltsPostProcessorAddChars := TltsPostProcessorAddChars( LoadProc('ltsPostProcessorAddChars'));
ltsPostProcessorClearRanges := TltsPostProcessorClearRanges( LoadProc('ltsPostProcessorClearRanges'));
+ ltsPostProcessorExecute := TltsPostProcessorExecute( LoadProc('ltsPostProcessorExecute'));
ltsPostProcessorFillColorCreate := TltsPostProcessorFillColorCreate( LoadProc('ltsPostProcessorFillColorCreate'));
ltsPostProcessorFillPatterCreate := TltsPostProcessorFillPatterCreate( LoadProc('ltsPostProcessorFillPatterCreate'));
ltsPostProcessorBorderCreate := TltsPostProcessorBorderCreate( LoadProc('ltsPostProcessorBorderCreate'));
ltsPostProcessorShadowCreate := TltsPostProcessorShadowCreate( LoadProc('ltsPostProcessorShadowCreate'));
+ ltsPostProcessorCustomCreate := TltsPostProcessorCustomCreate( LoadProc('ltsPostProcessorCustomCreate'));
ltsPostProcessorDestroy := TltsPostProcessorDestroy( LoadProc('ltsPostProcessorShadowCreate'));
+ ltsCharGetCharCode := TltsCharGetCharCode( LoadProc('ltsCharGetCharCode'));
+ ltsCharGetGlyphMetric := TltsCharGetGlyphMetric( LoadProc('ltsCharGetGlyphMetric'));
+ ltsCharSetGlyphMetric := TltsCharSetGlyphMetric( LoadProc('ltsCharSetGlyphMetric'));
+
ltsInitializeIntern := TltsInitialize( LoadProc('ltsInitialize'));
ltsGetLastErrorCode := TltsGetLastErrorCode( LoadProc('ltsGetLastErrorCode'));
ltsGetLastErrorMsg := TltsGetLastErrorMsg( LoadProc('ltsGetLastErrorMsg'));
@@ -1611,102 +1741,6 @@ begin
inherited Destroy;
end;
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//TltsRenderer//////////////////////////////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-function TltsRenderer.BeginBlock(const aTop, aLeft, aWidth, aHeight: Integer; const aFlags: TltsBlockFlags): TltsTextBlock;
-var
- h: TltsTextBlockHandle;
-begin
- h := ltsRendererBeginBlock(fHandle, aTop, aLeft, aWidth, aHeight, aFlags);
- if not Assigned(h) then
- raise TltsException.Create(ltsGetLastErrorMsg(), ltsGetLastErrorCode());
- result := TltsTextBlock.Create(h);
-end;
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TltsRenderer.EndBlock(var aTextBlock: TltsTextBlock);
-var
- err: TltsErrorCode;
-begin
- try
- err := ltsRendererEndBlock(fHandle, aTextBlock.Handle);
- if (err <> ltsErrNone) then
- raise TltsException.Create(ltsGetLastErrorMsg(), err);
- finally
- FreeAndNil(aTextBlock);
- end;
-end;
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-procedure TltsRenderer.AbortBlock(var aTextBlock: TltsTextBlock);
-var
- err: TltsErrorCode;
-begin
- try
- err := ltsRendererAbortBlock(fHandle, aTextBlock.Handle);
- if (err <> ltsErrNone) then
- raise TltsException.Create(ltsGetLastErrorMsg(), err);
- finally
- FreeAndNil(aTextBlock);
- end;
-end;
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-function TltsRenderer.GetTextWidthA(const aFont: TltsFont; const aText: PAnsiChar): Integer;
-begin
- result := ltsRendererGetTextWidthA(fHandle, aFont.Handle, aText);
- if (result < 0) then
- raise TltsException.Create(ltsGetLastErrorMsg(), ltsGetLastErrorCode());
-end;
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-function TltsRenderer.GetTextWidthW(const aFont: TltsFont; const aText: PWideChar): Integer;
-begin
- result := ltsRendererGetTextWidthW(fHandle, aFont.Handle, aText);
- if (result < 0) then
- raise TltsException.Create(ltsGetLastErrorMsg(), ltsGetLastErrorCode());
-end;
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-constructor TltsRenderer.Create(const aHandle: TltsRendererHandle);
-begin
- inherited Create;
- fHandle := aHandle;
-end;
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-destructor TltsRenderer.Destroy;
-begin
- inherited Destroy;
-end;
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//TltsRendererOpenGL////////////////////////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-constructor TltsRendererOpenGL.Create(const aContext: TltsContext; const aFormat: TltsFormat);
-var
- h: TltsRendererHandle;
-begin
- h := ltsRendererCreate(aContext.Handle, ltsRendererOpenGL, aFormat);
- if not Assigned(h) then
- raise TltsException.Create(ltsGetLastErrorMsg(), ltsGetLastErrorCode());
- inherited Create(h);
-end;
-
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-//TltsRendererOpenGLES//////////////////////////////////////////////////////////////////////////////////////////////////
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-constructor TltsRendererOpenGLES.Create(const aContext: TltsContext; const aFormat: TltsFormat);
-var
- h: TltsRendererHandle;
-begin
- h := ltsRendererCreate(aContext.Handle, ltsRendererOpenGLES, aFormat);
- if not Assigned(h) then
- raise TltsException.Create(ltsGetLastErrorMsg(), ltsGetLastErrorCode());
- inherited Create(h);
-end;
-
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TltsImage/////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1878,10 +1912,19 @@ begin
raise TltsException.Create(ltsGetLastErrorMsg(), err);
end;
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TltsImage.Create(const aHandle: TltsImageHandle);
+begin
+ inherited Create;
+ fHandle := aHandle;
+ fOwnsHandle := false;
+end;
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TltsImage.Create(const aContext: TltsContext);
begin
- fHandle := ltsImageCreate(aContext.Handle);
+ fOwnsHandle := true;
+ fHandle := ltsImageCreate(aContext.Handle);
if not Assigned(fHandle) then
raise TltsException.Create(ltsGetLastErrorMsg(), ltsGetLastErrorCode());
inherited Create;
@@ -1890,15 +1933,302 @@ end;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
destructor TltsImage.Destroy;
begin
- if Assigned(fHandle) then begin
+ if Assigned(fHandle) and fOwnsHandle then
ltsImageDestroy(fHandle);
- fHandle := nil;
+ fHandle := nil;
+ inherited Destroy;
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TltsChar//////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TltsChar.GetCharCode: WideChar;
+var
+ err: TltsErrorCode;
+begin
+ err := ltsCharGetCharCode(fHandle, result);
+ if (err <> ltsErrNone) then
+ raise TltsException.Create(ltsGetLastErrorMsg(), err);
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TltsChar.GetGlyphMetric: TltsGlyphMetric;
+var
+ err: TltsErrorCode;
+begin
+ err := ltsCharGetGlyphMetric(fHandle, result);
+ if (err <> ltsErrNone) then
+ raise TltsException.Create(ltsGetLastErrorMsg(), err);
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TltsChar.SetGlyphMetric(aValue: TltsGlyphMetric);
+var
+ err: TltsErrorCode;
+begin
+ err := ltsCharSetGlyphMetric(fHandle, aValue);
+ if (err <> ltsErrNone) then
+ raise TltsException.Create(ltsGetLastErrorMsg(), err);
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TltsChar.Create(const aHandle: TltsCharHandle);
+begin
+ inherited Create;
+ fHandle := aHandle;
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TltsRenderer//////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TltsRenderer.BeginBlock(const aTop, aLeft, aWidth, aHeight: Integer; const aFlags: TltsBlockFlags): TltsTextBlock;
+var
+ h: TltsTextBlockHandle;
+begin
+ h := ltsRendererBeginBlock(fHandle, aTop, aLeft, aWidth, aHeight, aFlags);
+ if not Assigned(h) then
+ raise TltsException.Create(ltsGetLastErrorMsg(), ltsGetLastErrorCode());
+ result := TltsTextBlock.Create(h);
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TltsRenderer.EndBlock(var aTextBlock: TltsTextBlock);
+var
+ err: TltsErrorCode;
+begin
+ try
+ err := ltsRendererEndBlock(fHandle, aTextBlock.Handle);
+ if (err <> ltsErrNone) then
+ raise TltsException.Create(ltsGetLastErrorMsg(), err);
+ finally
+ FreeAndNil(aTextBlock);
end;
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TltsRenderer.AbortBlock(var aTextBlock: TltsTextBlock);
+var
+ err: TltsErrorCode;
+begin
+ try
+ err := ltsRendererAbortBlock(fHandle, aTextBlock.Handle);
+ if (err <> ltsErrNone) then
+ raise TltsException.Create(ltsGetLastErrorMsg(), err);
+ finally
+ FreeAndNil(aTextBlock);
+ end;
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TltsRenderer.GetTextWidthA(const aFont: TltsFont; const aText: PAnsiChar): Integer;
+begin
+ result := ltsRendererGetTextWidthA(fHandle, aFont.Handle, aText);
+ if (result < 0) then
+ raise TltsException.Create(ltsGetLastErrorMsg(), ltsGetLastErrorCode());
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TltsRenderer.GetTextWidthW(const aFont: TltsFont; const aText: PWideChar): Integer;
+begin
+ result := ltsRendererGetTextWidthW(fHandle, aFont.Handle, aText);
+ if (result < 0) then
+ raise TltsException.Create(ltsGetLastErrorMsg(), ltsGetLastErrorCode());
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TltsRenderer.Create(const aHandle: TltsRendererHandle);
+begin
+ inherited Create;
+ fHandle := aHandle;
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+destructor TltsRenderer.Destroy;
+begin
inherited Destroy;
end;
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TltsRendererOpenGL////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TltsRendererOpenGL.Create(const aContext: TltsContext; const aFormat: TltsFormat);
+var
+ h: TltsRendererHandle;
+begin
+ h := ltsRendererCreate(aContext.Handle, ltsRendererOpenGL, aFormat);
+ if not Assigned(h) then
+ raise TltsException.Create(ltsGetLastErrorMsg(), ltsGetLastErrorCode());
+ inherited Create(h);
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TltsRendererOpenGLES//////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TltsRendererOpenGLES.Create(const aContext: TltsContext; const aFormat: TltsFormat);
+var
+ h: TltsRendererHandle;
+begin
+ h := ltsRendererCreate(aContext.Handle, ltsRendererOpenGLES, aFormat);
+ if not Assigned(h) then
+ raise TltsException.Create(ltsGetLastErrorMsg(), ltsGetLastErrorCode());
+ inherited Create(h);
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TltsRendererCustom////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure ltsRendererCustomBeginRender(aArgs: Pointer); stdcall;
+begin
+ TltsRendererCustom(aArgs).BeginRender;
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure ltsRendererCustomEndRender(aArgs: Pointer); stdcall;
+begin
+ TltsRendererCustom(aArgs).EndRender;
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function ltsRendererCustomGetDrawPos(aArgs: Pointer): TltsPosition; stdcall;
+begin
+ result := TltsRendererCustom(aArgs).GetDrawPos;
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure ltsRendererCustomSetDrawPos(const aValue: TltsPosition; aArgs: Pointer); stdcall;
+begin
+ TltsRendererCustom(aArgs).SetDrawPos(aValue);
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure ltsRendererCustomMoveDrawPos(const aOffset: TltsPosition; aArgs: Pointer); stdcall;
+begin
+ TltsRendererCustom(aArgs).MoveDrawPos(aOffset);
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure ltsRendererCustomSetColor(const aValue: TltsColor4f; aArgs: Pointer); stdcall;
+begin
+ TltsRendererCustom(aArgs).SetColor(aValue);
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure ltsRendererCustomRender(const aRef: Pointer; const aForcedWidth: Integer; aArgs: Pointer); stdcall;
+begin
+ TltsRendererCustom(aArgs).Render(aRef, aForcedWidth);
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function ltsRendererCustomCreateRef(const aChar: TltsCharHandle; const aImage: TltsImageHandle; aArgs: Pointer): Pointer; stdcall;
+var
+ chr: TltsChar;
+ img: TltsImage;
+begin
+ chr := TltsChar.Create(aChar);
+ img := TltsImage.Create(aImage);
+ try
+ result := TltsRendererCustom(aArgs).CreateRenderRef(chr, img);
+ finally
+ FreeAndNil(img);
+ FreeAndNil(chr);
+ end;
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure ltsRendererCustomFreeRef(const aRef: Pointer; aArgs: Pointer); stdcall;
+begin
+ TltsRendererCustom(aArgs).FreeRenderRef(aRef);
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TltsRendererCustom.BeginRender;
+begin
+ // DUMMY
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TltsRendererCustom.EndRender;
+begin
+ // DUMMY
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TltsRendererCustom.GetDrawPos: TltsPosition;
+begin
+ result := fDrawPos;
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TltsRendererCustom.SetDrawPos(const aValue: TltsPosition);
+begin
+ fDrawPos := aValue;
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TltsRendererCustom.MoveDrawPos(const aOffset: TltsPosition);
+begin
+ fDrawPos.x := fDrawPos.x + aOffset.x;
+ fDrawPos.y := fDrawPos.y + aOffset.y;
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TltsRendererCustom.SetColor(const aValue: TltsColor4f);
+begin
+ fColor := aValue;
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TltsRendererCustom.Render(const aRenderRef: Pointer; const aForcedWidth: Integer);
+begin
+ // DUMMY
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TltsRendererCustom.CreateRenderRef(const aChar: TltsChar; const aImage: TltsImage): Pointer;
+begin
+ result := nil; // DUMMY
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TltsRendererCustom.FreeRenderRef(const aRenderRef: Pointer);
+begin
+ // DUMMY
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TltsRendererCustom.Create(const aContext: TltsContext; const aFormat: TltsFormat);
+var
+ h: TltsRendererHandle;
+ d: TltsRendererCustomData;
+begin
+ d.args := self;
+ d.BeginRender := @ltsRendererCustomBeginRender;
+ d.EndRender := @ltsRendererCustomEndRender;
+ d.GetDrawPos := @ltsRendererCustomGetDrawPos;
+ d.SetDrawPos := @ltsRendererCustomSetDrawPos;
+ d.MoveDrawPos := @ltsRendererCustomMoveDrawPos;
+ d.SetColor := @ltsRendererCustomSetColor;
+ d.Render := @ltsRendererCustomRender;
+ d.CreatRef := @ltsRendererCustomCreateRef;
+ d.FreeRef := @ltsRendererCustomFreeRef;
+ h := ltsRendererCustomCreate(aContext.Handle, aFormat, @d);
+ if not Assigned(h) then
+ raise TltsException.Create(ltsGetLastErrorMsg(), ltsGetLastErrorCode());
+ inherited Create(h);
+end;
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TltsPostProcessor/////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TltsPostProcessor.Execute(const aChar: TltsChar; const aImage: TltsImage);
+var
+ err: TltsErrorCode;
+begin
+ err := ltsPostProcessorExecute(fHandle, aChar.Handle, aImage.Handle);
+ if (err <> ltsErrNone) then
+ raise TltsException.Create(ltsGetLastErrorMsg(), err);
+end;
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TltsPostProcessor.AddRange(const aUsage: TltsCharRangeUsage; const aStart, aStop: WideChar);
var
@@ -2026,5 +2356,117 @@ begin
inherited Create(h);
end;
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TltsPostProcessorCustom///////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure ltsPostProcessorExecuteCallback(const aChar: TltsCharHandle; const aImage: TltsImageHandle; aArgs: Pointer);
+var
+ chr: TltsChar;
+ img: TltsImage;
+begin
+ chr := TltsChar.Create(aChar);
+ img := TltsImage.Create(aImage);
+ try
+ TltsPostProcessorCustom(aArgs).Execute(chr, img);
+ finally
+ FreeAndNil(img);
+ FreeAndNil(chr);
+ end;
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TltsPostProcessorCustom.Create(const aContext: TltsContext);
+var
+ h: TltsPostProcessorHandle;
+ p: TltsPostProcessorCustomData;
+begin
+ p.args := self;
+ p.execute := @ltsPostProcessorExecuteCallback;
+ h := ltsPostProcessorCustomCreate(aContext.Handle, @p);
+ if not Assigned(h) then
+ raise TltsException.Create(ltsGetLastErrorMsg(), ltsGetLastErrorCode());
+ inherited Create(h);
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TltsPostProcessorList/////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TltsPostProcessorList.GetCount: Integer;
+begin
+ result := fItems.Count;
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TltsPostProcessorList.GetItem(const aIndex: Integer): TltsPostProcessor;
+begin
+ result := TltsPostProcessor(fItems[aIndex]);
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TltsPostProcessorList.GetOwnsObjects: Boolean;
+begin
+ result := fItems.OwnsObjects;
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TltsPostProcessorList.SetOwnsObjects(aValue: Boolean);
+begin
+ fItems.OwnsObjects := aValue;
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TltsPostProcessorList.Execute(const aChar: TltsChar; const aImage: TltsImage);
+var
+ i: Integer;
+begin
+ inherited Execute(aChar, aImage);
+ for i := 0 to fItems.Count-1 do
+ TltsPostProcessor(fItems[i]).Execute(aChar, aImage);
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TltsPostProcessorList.Add(const aPostProcessor: TltsPostProcessor);
+begin
+ fItems.Add(aPostProcessor);
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TltsPostProcessorList.Delete(const aIndex: Integer);
+begin
+ fItems.Delete(aIndex);
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TltsPostProcessorList.Clear;
+begin
+ fItems.Clear;
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TltsPostProcessorList.Remove(const aPostProcessor: TltsPostProcessor): Integer;
+begin
+ result := fItems.Remove(aPostProcessor);
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TltsPostProcessorList.IndexOf(const aPostProcessor: TltsPostProcessor): Integer;
+begin
+ result := fItems.IndexOf(aPostProcessor);
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TltsPostProcessorList.Create(const aContext: TltsContext; const aOwnsObjects: Boolean);
+begin
+ inherited Create(aContext);
+ fItems := TObjectList.Create(aOwnsObjects);
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+destructor TltsPostProcessorList.Destroy;
+begin
+ FreeAndNil(fItems);
+ inherited Destroy;
+end;
+
end.
diff --git a/libTextSuite.lpi b/libTextSuite.lpi
index b26456e..fa287e9 100644
--- a/libTextSuite.lpi
+++ b/libTextSuite.lpi
@@ -359,7 +359,7 @@
-
+
@@ -413,6 +413,11 @@
+
+
+
+
+
diff --git a/libTextSuite.lpr b/libTextSuite.lpr
index b6d8b2f..0e0fc54 100644
--- a/libTextSuite.lpr
+++ b/libTextSuite.lpr
@@ -4,7 +4,8 @@ library libTextSuite;
uses
Classes, SysUtils,
- ultsContext, ultsRenderer, ultsTextBlock, ultsGeneral, ultsFont, ultsFontCreator, ultsImage, ultsPostProcessor;
+ ultsContext, ultsRenderer, ultsTextBlock, ultsGeneral, ultsFont, ultsFontCreator,
+ ultsImage, ultsPostProcessor, ultsChar;
exports
ltsContextCreate,
@@ -97,6 +98,10 @@ exports
ltsPostProcessorBorderCreate,
ltsPostProcessorShadowCreate,
+ ltsCharGetCharCode,
+ ltsCharGetGlyphMetric,
+ ltsCharSetGlyphMetric,
+
ltsInitialize,
ltsGetLastErrorCode,
ltsGetLastErrorMsg,
diff --git a/ultsChar.pas b/ultsChar.pas
new file mode 100644
index 0000000..02904d7
--- /dev/null
+++ b/ultsChar.pas
@@ -0,0 +1,77 @@
+unit ultsChar;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils,
+ utsTextSuite, ultsTypes;
+
+function ltsCharGetCharCode (const aHandle: TltsCharHandle; var aValue: WideChar): TltsErrorCode; stdcall;
+function ltsCharGetGlyphMetric(const aHandle: TltsCharHandle; var aValue: TtsGlyphMetric): TltsErrorCode; stdcall;
+function ltsCharSetGlyphMetric(const aHandle: TltsCharHandle; const aValue: TtsGlyphMetric): TltsErrorCode; stdcall;
+
+implementation
+
+uses
+ ultsUtils;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//ltsChar///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function ltsCharGetCharCode(const aHandle: TltsCharHandle; var aValue: WideChar): TltsErrorCode; stdcall;
+var
+ c: TtsChar;
+begin
+ try
+ result := ltsErrNone;
+ if CheckCharHandle(aHandle, c)
+ then aValue := c.CharCode
+ else result := LastErrorCode;
+ except
+ on ex: Exception do begin
+ SetLastError(ex);
+ result := LastErrorCode;
+ end;
+ end;
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function ltsCharGetGlyphMetric(const aHandle: TltsCharHandle; var aValue: TtsGlyphMetric): TltsErrorCode; stdcall;
+var
+ c: TtsChar;
+begin
+ try
+ result := ltsErrNone;
+ if CheckCharHandle(aHandle, c)
+ then aValue := c.GlyphMetric
+ else result := LastErrorCode;
+ except
+ on ex: Exception do begin
+ SetLastError(ex);
+ result := LastErrorCode;
+ end;
+ end;
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function ltsCharSetGlyphMetric(const aHandle: TltsCharHandle; const aValue: TtsGlyphMetric): TltsErrorCode; stdcall;
+var
+ c: TtsChar;
+begin
+ try
+ result := ltsErrNone;
+ if CheckCharHandle(aHandle, c)
+ then c.GlyphMetric := aValue
+ else result := LastErrorCode;
+ except
+ on ex: Exception do begin
+ SetLastError(ex);
+ result := LastErrorCode;
+ end;
+ end;
+end;
+
+end.
+
diff --git a/ultsPostProcessor.pas b/ultsPostProcessor.pas
index 5f8ce95..0ca4b5f 100644
--- a/ultsPostProcessor.pas
+++ b/ultsPostProcessor.pas
@@ -8,9 +8,27 @@ uses
Classes, SysUtils,
ultsTypes, utsTextSuite;
+type
+ TltsPostProcessorExecuteFunc = procedure(const aCharHandle: TltsCharHandle; const aImageHandle: TltsImageHandle; aArgs: Pointer); stdcall;
+
+ PltsPostProcessorCustomData = ^TltsPostProcessorCustomData;
+ TltsPostProcessorCustomData = packed record
+ args: Pointer;
+ execute: TltsPostProcessorExecuteFunc;
+ end;
+
+ TltsPostProcessorCustom = class(TtsPostProcessor)
+ private
+ fData: TltsPostProcessorCustomData;
+ public
+ function Execute(const aChar: TtsChar; const aImage: TtsImage): Boolean; override;
+ constructor Create(const aContext: TtsContext; const aData: TltsPostProcessorCustomData);
+ end;
+
function ltsPostProcessorAddRange (const aHandle: TltsPostProcessorHandle; const aUsage: TtsCharRangeUsage; const aStart, aStop: WideChar): TltsErrorCode; stdcall;
function ltsPostProcessorAddChars (const aHandle: TltsPostProcessorHandle; const aUsage: TtsCharRangeUsage; const aChars: PWideChar): TltsErrorCode; stdcall;
function ltsPostProcessorClearRanges (const aHandle: TltsPostProcessorHandle): TltsErrorCode; stdcall;
+function ltsPostProcessorExecute (const aHandle: TltsPostProcessorHandle; const aChar: TltsCharHandle; const aImage: TltsImageHandle): TltsErrorCode; stdcall;
function ltsPostProcessorFillColorCreate (const aContext: TltsContextHandle; const aColor: TtsColor4f;
const aModes: TtsImageModes; const aChannels: TtsColorChannels): TltsPostProcessorHandle; stdcall;
@@ -20,6 +38,7 @@ function ltsPostProcessorBorderCreate (const aContext: TltsContextHandle;
const aColor: TtsColor4f; const aKeepSize: Boolean): TltsPostProcessorHandle; stdcall;
function ltsPostProcessorShadowCreate (const aContext: TltsContextHandle; const aRadius, aStrength: Single;
const aOffset: TtsPosition; const aColor: TtsColor4f): TltsPostProcessorHandle; stdcall;
+function ltsPostProcessorCustomCreate (const aContext: TltsContextHandle; const aData: PltsPostProcessorCustomData): TltsPostProcessorHandle; stdcall;
function ltsPostProcessorDestroy (const aHandle: TltsPostProcessorHandle): TltsErrorCode; stdcall;
implementation
@@ -83,6 +102,28 @@ begin
end;
end;
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function ltsPostProcessorExecute(const aHandle: TltsPostProcessorHandle; const aChar: TltsCharHandle; const aImage: TltsImageHandle): TltsErrorCode; stdcall;
+var
+ pp: TtsPostProcessor;
+ c: TtsChar;
+ i: TtsImage;
+begin
+ try
+ result := ltsErrNone;
+ if CheckPostProcessorHandle(aHandle, TtsPostProcessor, pp) and
+ CheckCharHandle(aChar, c) and
+ CheckImageHandle(aImage, i)
+ then pp.Execute(c, i)
+ else result := LastErrorCode;
+ except
+ on ex: Exception do begin
+ SetLastError(ex);
+ result := LastErrorCode;
+ end;
+ end;
+end;
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function ltsPostProcessorFillColorCreate(const aContext: TltsContextHandle; const aColor: TtsColor4f; const aModes: TtsImageModes; const aChannels: TtsColorChannels): TltsPostProcessorHandle; stdcall;
var
@@ -169,6 +210,29 @@ begin
end;
end;
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function ltsPostProcessorCustomCreate(const aContext: TltsContextHandle; const aData: PltsPostProcessorCustomData): TltsPostProcessorHandle; stdcall;
+var
+ c: TtsContext;
+ pp: TtsPostProcessor;
+begin
+ try
+ result := nil;
+ if not Assigned(aData) then begin
+ SetLastError(ltsErrInvalidValue, 'parameter ''aData'' is not assigned');
+ end else if CheckContextHandle(aContext, c) then begin
+ pp := TltsPostProcessorCustom.Create(c, aData^);
+ AddReference(ltsObjTypePostProcessor, pp);
+ result := pp;
+ end;
+ except
+ on ex: Exception do begin
+ SetLastError(ex);
+ result := nil;
+ end;
+ end;
+end;
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function ltsPostProcessorDestroy(const aHandle: TltsPostProcessorHandle): TltsErrorCode; stdcall;
var
@@ -193,5 +257,30 @@ begin
end;
end;
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TltsPostProcessorCustom///////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TltsPostProcessorCustom.Execute(const aChar: TtsChar; const aImage: TtsImage): Boolean;
+begin
+ result := inherited Execute(aChar, aImage);
+ if result then begin
+ AddReference(ltsObjTypeChar, aChar);
+ AddReference(ltsObjTypeImage, aImage);
+ try
+ fData.execute(aChar, aImage, fData.args);
+ finally
+ DelReference(ltsObjTypeChar, aChar);
+ DelReference(ltsObjTypeImage, aImage);
+ end;
+ end;
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TltsPostProcessorCustom.Create(const aContext: TtsContext; const aData: TltsPostProcessorCustomData);
+begin
+ inherited Create(aContext);
+ fData := aData;
+end;
+
end.
diff --git a/ultsRenderer.pas b/ultsRenderer.pas
index 103c891..08dea48 100644
--- a/ultsRenderer.pas
+++ b/ultsRenderer.pas
@@ -7,9 +7,38 @@ interface
uses
Classes, SysUtils,
ultsTypes,
- utsTextSuite, utsUtils;
+ utsTextSuite, utsUtils, utsRenderer, utsTypes;
+
+type
+ TltsRendererCustomBeginRender = procedure(aArgs: Pointer); stdcall;
+ TltsRendererCustomEndRender = procedure(aArgs: Pointer); stdcall;
+ TltsRendererCustomGetDrawPos = function (aArgs: Pointer): TtsPosition; stdcall;
+ TltsRendererCustomSetDrawPos = procedure(const aValue: TtsPosition; aArgs: Pointer); stdcall;
+ TltsRendererCustomMoveDrawPos = procedure(const aOffset: TtsPosition; aArgs: Pointer); stdcall;
+ TltsRendererCustomSetColor = procedure(const aValue: TtsColor4f; aArgs: Pointer); stdcall;
+ TltsRendererCustomRender = procedure(const aRef: Pointer; const aForcedWidth: Integer; aArgs: Pointer); stdcall;
+
+ TltsRendererCustomCreateRef = function (const aChar: TltsCharHandle; const aImage: TltsImageHandle; aArgs: Pointer): Pointer; stdcall;
+ TltsRendererCustomFreeRef = procedure(const aRef: Pointer; aArgs: Pointer); stdcall;
+
+ PltsRendererCustomData = ^TltsRendererCustomData;
+ TltsRendererCustomData = packed record
+ args: Pointer;
+
+ BeginRender: TltsRendererCustomBeginRender;
+ EndRender: TltsRendererCustomEndRender;
+ GetDrawPos: TltsRendererCustomGetDrawPos;
+ SetDrawPos: TltsRendererCustomSetDrawPos;
+ MoveDrawPos: TltsRendererCustomMoveDrawPos;
+ SetColor: TltsRendererCustomSetColor;
+ Render: TltsRendererCustomRender;
+
+ CreatRef: TltsRendererCustomCreateRef;
+ FreeRef: TltsRendererCustomFreeRef;
+ end;
function ltsRendererCreate (const aHandle: TltsContextHandle; const aType: TltsRendererType; const aFormat: TtsFormat): TltsRendererHandle; stdcall;
+function ltsRendererCustomCreate (const aHandle: TltsContextHandle; const aFormat: TtsFormat; const aData: PltsRendererCustomData): TltsRendererHandle; stdcall;
function ltsRendererBeginBlock (const aHandle: TltsRendererHandle; const aTop, aLeft, aWidth, aHeight: Integer; const aFlags: TtsBlockFlags): TltsTextBlockHandle; stdcall;
function ltsRendererEndBlock (const aHandle: TltsRendererHandle; const aBlock: TltsTextBlockHandle): TltsErrorCode; stdcall;
function ltsRendererAbortBlock (const aHandle: TltsRendererHandle; const aBlock: TltsTextBlockHandle): TltsErrorCode; stdcall;
@@ -35,6 +64,30 @@ type
procedure DelSlave(const aSlave: TtsRefManager); override;
end;
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+ TltsRendererCustom = class(TtsRenderer)
+ { TtsBlockRenderer }
+ protected
+ procedure BeginRender; override;
+ procedure EndRender; override;
+ function GetDrawPos: TtsPosition; override;
+ procedure SetDrawPos(const aValue: TtsPosition); override;
+ procedure MoveDrawPos(const aOffset: TtsPosition); override;
+ procedure SetColor(const aValue: TtsColor4f); override;
+ procedure Render(const aRenderRef: TtsRenderRef; const aForcedWidth: Integer); override;
+
+ { TtsRenderRefGenerator }
+ public
+ function CreateRenderRef(const aChar: TtsChar; const aImage: TtsImage): TtsRenderRef; override;
+ procedure FreeRenderRef(const aRenderRef: TtsRenderRef); override;
+
+ { TltsRendererCustom }
+ private
+ fData: TltsRendererCustomData;
+ public
+ constructor Create(const aContext: TtsContext; const aFormat: TtsFormat; const aData: TltsRendererCustomData);
+ end;
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TltsRendererOpenGL////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -53,6 +106,87 @@ begin
inherited DelSlave(aSlave);
end;
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//TltsRendererCustom////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TltsRendererCustom.CreateRenderRef(const aChar: TtsChar; const aImage: TtsImage): TtsRenderRef;
+begin
+ AddReference(ltsObjTypeChar, aChar);
+ AddReference(ltsObjTypeImage, aImage);
+ try
+ if Assigned(fData.CreatRef)
+ then result := fData.CreatRef(aChar, aImage, fData.args)
+ else result := nil;
+ finally
+ DelReference(ltsObjTypeChar, aChar);
+ DelReference(ltsObjTypeImage, aImage);
+ end;
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TltsRendererCustom.FreeRenderRef(const aRenderRef: TtsRenderRef);
+begin
+ if Assigned(fData.FreeRef) then
+ fData.FreeRef(aRenderRef, fData.args);
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TltsRendererCustom.BeginRender;
+begin
+ if Assigned(fData.BeginRender) then
+ fData.BeginRender(fData.args);
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TltsRendererCustom.EndRender;
+begin
+ if Assigned(fData.BeginRender) then
+ fData.BeginRender(fData.args);
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function TltsRendererCustom.GetDrawPos: TtsPosition;
+begin
+ if Assigned(fData.BeginRender)
+ then result := fData.GetDrawPos(fData.args)
+ else result := tsPosition(0, 0);
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TltsRendererCustom.SetDrawPos(const aValue: TtsPosition);
+begin
+ if Assigned(fData.BeginRender) then
+ fData.SetDrawPos(aValue, fData.args);
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TltsRendererCustom.MoveDrawPos(const aOffset: TtsPosition);
+begin
+ if Assigned(fData.BeginRender) then
+ fData.MoveDrawPos(aOffset, fData.args);
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TltsRendererCustom.SetColor(const aValue: TtsColor4f);
+begin
+ if Assigned(fData.BeginRender) then
+ fData.SetColor(aValue, fData.args);
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+procedure TltsRendererCustom.Render(const aRenderRef: TtsRenderRef; const aForcedWidth: Integer);
+begin
+ if Assigned(fData.BeginRender) then
+ fData.Render(aRenderRef, aForcedWidth, fData.args);
+end;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+constructor TltsRendererCustom.Create(const aContext: TtsContext; const aFormat: TtsFormat; const aData: TltsRendererCustomData);
+begin
+ inherited Create(aContext, aFormat);
+ fData := aData;
+end;
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//Renderer//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -74,7 +208,6 @@ begin
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;
@@ -89,6 +222,38 @@ begin
end;
end;
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function ltsRendererCustomCreate(const aHandle: TltsContextHandle; const aFormat: TtsFormat; const aData: PltsRendererCustomData): TltsRendererHandle; stdcall;
+var
+ c: TtsContext;
+ r: TtsRenderer;
+begin
+ try
+ result := nil;
+ if not CheckContextHandle(aHandle, c) then
+ exit;
+
+ if not Assigned(aData) then begin
+ SetLastError(ltsErrInvalidValue, Format('prameter ''aData'' is not assigned', [aFormat]));
+ exit;
+ end;
+
+ if not ValidateFormat(aFormat) then begin
+ SetLastError(ltsErrInvalidEnum, Format('%d is not a valid format', [aFormat]));
+ exit;
+ end;
+
+ r := TltsRendererCustom.Create(c, aFormat, aData^);
+ AddReference(ltsObjTypeRenderer, r);
+ result := r;
+ except
+ on ex: Exception do begin
+ SetLastError(ex);
+ result := nil;
+ end;
+ end;
+end;
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function ltsRendererBeginBlock(const aHandle: TltsRendererHandle; const aTop, aLeft, aWidth, aHeight: Integer; const aFlags: TtsBlockFlags): TltsTextBlockHandle; stdcall;
var
diff --git a/ultsTypes.pas b/ultsTypes.pas
index ae54810..0291b77 100644
--- a/ultsTypes.pas
+++ b/ultsTypes.pas
@@ -39,15 +39,15 @@ type
ltsObjTypeFont,
ltsObjTypeTextBlock,
ltsObjTypeImage,
- ltsObjTypePostProcessor
+ ltsObjTypePostProcessor,
+ ltsObjTypeChar
);
{$Z4}
TltsRendererType = (
ltsRendererUnknown,
ltsRendererOpenGL,
- ltsRendererOpenGLES,
- ltsRendererCustom
+ ltsRendererOpenGLES
);
{$Z4}
@@ -66,6 +66,7 @@ type
TltsFontHandle = TltsHandle;
TltsPostProcessorHandle = TltsHandle;
TltsImageHandle = TltsHandle;
+ TltsCharHandle = TltsHandle;
TltsStreamOrigin = (
ltsStreamOriginBegin = Integer(soBeginning),
diff --git a/ultsUtils.pas b/ultsUtils.pas
index e52796f..732916f 100644
--- a/ultsUtils.pas
+++ b/ultsUtils.pas
@@ -23,6 +23,7 @@ function CheckTextBlockHandle(const aHandle: TltsTextBlockHandle; out aTextBlock
function CheckFontHandle(const aHandle: TltsFontHandle; out aFont: TtsFont): Boolean;
function CheckFontCreatorHandle(const aHandle: TltsFontCreatorHandle; out aFontCreator: TtsFontCreator): Boolean;
function CheckImageHandle(const aHandle: TltsImageHandle; out aImage: TtsImage): Boolean;
+function CheckCharHandle(const aHandle: TltsCharHandle; out aChar: TtsChar): Boolean;
function CheckPostProcessorHandle(const aHandle: TltsPostProcessorHandle; const aType: TtsPostProcessorClass; out aPostProcessor): Boolean;
procedure AddReference(const aType: TltsObjectType; const aRef: TObject);
@@ -61,6 +62,7 @@ type
TtsFontCreatorHashSet = specialize TutlHashSet;
TtsImageHashSet = specialize TutlHashSet;
TtsPostProcessorHashSet = specialize TutlHashSet;
+ TtsCharHashSet = specialize TutlHashSet;
var
IsInitilized: Boolean = false;
@@ -72,6 +74,7 @@ var
FontCreators: TtsFontCreatorHashSet = nil;
Images: TtsImageHashSet = nil;
PostProcessors: TtsPostProcessorHashSet = nil;
+ Chars: TtsCharHashSet = nil;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure SetLastError(const aEx: Exception);
@@ -167,6 +170,18 @@ begin
end;
end;
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+function CheckCharHandle(const aHandle: TltsCharHandle; out aChar: TtsChar): Boolean;
+begin
+ result := CheckIfInitialized;
+ if result then begin
+ aChar := TtsChar(aHandle);
+ result := Chars.Contains(aChar);
+ if not result then
+ SetLastError(ltsErrInvalidImageHandle, Format('0x%.16x is no a valid char handle', [{%H-}PtrUInt(aHandle)]));
+ end;
+end;
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function CheckPostProcessorHandle(const aHandle: TltsPostProcessorHandle; const aType: TtsPostProcessorClass; out aPostProcessor): Boolean;
begin
@@ -197,6 +212,7 @@ begin
ltsObjTypeFontCreator: FontCreators.Add(aRef as TtsFontCreator);
ltsObjTypeImage: Images.Add(aRef as TtsImage);
ltsObjTypePostProcessor: PostProcessors.Add(aRef as TtsPostProcessor);
+ ltsObjTypeChar: Chars.Add(aRef as TtsChar);
end;
end;
@@ -211,6 +227,7 @@ begin
ltsObjTypeFontCreator: FontCreators.Remove(aRef as TtsFontCreator);
ltsObjTypeImage: Images.Remove(aRef as TtsImage);
ltsObjTypePostProcessor: PostProcessors.Remove(aRef as TtsPostProcessor);
+ ltsObjTypeChar: Chars.Remove(aRef as TtsChar);
end;
end;
@@ -230,7 +247,9 @@ begin
else if (aRef is TtsImage) then
DelReference(ltsObjTypeImage, aRef)
else if (aRef is TtsPostProcessor) then
- DelReference(ltsObjTypePostProcessor, aRef);
+ DelReference(ltsObjTypePostProcessor, aRef)
+ else if (aRef is TtsChar) then
+ DelReference(ltsObjTypeChar, aRef);
end;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -267,6 +286,7 @@ begin
Fonts := TtsFontHashSet.Create(false);
Images := TtsImageHashSet.Create(false);
PostProcessors := TtsPostProcessorHashSet.Create(false);
+ Chars := TtsCharHashSet.Create(false);
IsInitilized := true;
end;
@@ -274,6 +294,7 @@ end;
procedure Finalize;
begin
IsInitilized := false;
+ FreeAndNil(Chars);
FreeAndNil(PostProcessors);
FreeAndNil(Images);
FreeAndNil(TextBlocks);