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