Browse Source

* implemented custom post processor

* implemented custom renderer
* implemented post processor list
* implemented TltsChar
* updated submodule: TextSuite
master
Bergmann89 8 years ago
parent
commit
b7d65f1cf6
9 changed files with 946 additions and 141 deletions
  1. +1
    -1
      TextSuite
  2. +574
    -132
      header/ulibTextSuite.pas
  3. +6
    -1
      libTextSuite.lpi
  4. +6
    -1
      libTextSuite.lpr
  5. +77
    -0
      ultsChar.pas
  6. +89
    -0
      ultsPostProcessor.pas
  7. +167
    -2
      ultsRenderer.pas
  8. +4
    -3
      ultsTypes.pas
  9. +22
    -1
      ultsUtils.pas

+ 1
- 1
TextSuite

@@ -1 +1 @@
Subproject commit 414584359b16746bee43cf52d661ee6112ee824b
Subproject commit a5f9cf19e54f765078e9490a6d678b5b3f87a3dc

+ 574
- 132
header/ulibTextSuite.pas View File

@@ -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.


+ 6
- 1
libTextSuite.lpi View File

@@ -359,7 +359,7 @@
<FormatVersion Value="1"/>
</local>
</RunParams>
<Units Count="11">
<Units Count="12">
<Unit0>
<Filename Value="libTextSuite.lpr"/>
<IsPartOfProject Value="True"/>
@@ -413,6 +413,11 @@
<IsPartOfProject Value="True"/>
<UnitName Value="ultsPostProcessor"/>
</Unit10>
<Unit11>
<Filename Value="ultsChar.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="ultsChar"/>
</Unit11>
</Units>
</ProjectOptions>
<CompilerOptions>


+ 6
- 1
libTextSuite.lpr View File

@@ -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,


+ 77
- 0
ultsChar.pas View File

@@ -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.


+ 89
- 0
ultsPostProcessor.pas View File

@@ -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.


+ 167
- 2
ultsRenderer.pas View File

@@ -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


+ 4
- 3
ultsTypes.pas View File

@@ -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),


+ 22
- 1
ultsUtils.pas View File

@@ -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<TtsFontCreator>;
TtsImageHashSet = specialize TutlHashSet<TtsImage>;
TtsPostProcessorHashSet = specialize TutlHashSet<TtsPostProcessor>;
TtsCharHashSet = specialize TutlHashSet<TtsChar>;

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);


Loading…
Cancel
Save