diff --git a/TextSuite b/TextSuite index 893e916..4145843 160000 --- a/TextSuite +++ b/TextSuite @@ -1 +1 @@ -Subproject commit 893e9166cd762b505bb8cd72ce7f999a1b5e97b3 +Subproject commit 414584359b16746bee43cf52d661ee6112ee824b diff --git a/libTextSuite.lpi b/libTextSuite.lpi index 6930e7e..1607976 100644 --- a/libTextSuite.lpi +++ b/libTextSuite.lpi @@ -31,12 +31,60 @@ - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libTextSuite.lpr b/libTextSuite.lpr index 1a9b018..77105e8 100644 --- a/libTextSuite.lpr +++ b/libTextSuite.lpr @@ -4,365 +4,8 @@ library libTextSuite; uses Classes, SysUtils, - utsTextSuite, utsTypes, utsRendererOpenGL, utsRendererOpenGLES, - uutlGenerics; + ultsContext, ultsRenderer, ultsTextBlock, ultsGeneral, ultsFont, ultsFontCreator, ultsImage, ultsPostProcessor; -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//external types and contstants///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -type - {$Z4} - TltsErrorCode = ( - ltsErrUnknown = -1, - ltsErrNone = 0, - - // misc - ltsErrNotInitialized = 1, - ltsErrInvalidEnum = 2, - ltsErrInvalidValue = 3, - ltsErrInvalidOperation = 4, - - // invalid handles - ltsErrInvalidContextHandle = 100, - ltsErrInvalidRendererHandle = 101 - ); - - {$Z4} - TltsRendererType = ( - ltsRendererOpenGL, - ltsRendererOpenGLES, - ltsRendererCustom - ); - - TltsContextHandle = Pointer; - TltsRendererHandle = Pointer; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//internal types and contstants///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TltsContext = class(TtsContext) - public - destructor Destroy; override; - end; - TtsContextHashSet = specialize TutlHashSet; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - TltsRendererOpenGL = class(TtsRendererOpenGL) - public - // TODO destructor Destroy; override; - end; - - TltsRendererOpenGLES = class(TtsRendererOpenGLES) - public - // TODO destructor Destroy; override; - end; - - { TODO - TltsRendererCustom = class(TtsRenderer) - protected - function CreateRenderRef(const aChar: TtsChar; const aCharImage: TtsImage): TtsCharRenderRef; override; - procedure FreeRenderRef(const aCharRef: TtsCharRenderRef); override; - - procedure BeginRender; override; - procedure EndRender; override; - - procedure SetDrawPos(const X, Y: Integer); override; - function GetDrawPos: TtsPosition; override; - procedure MoveDrawPos(const X, Y: Integer); override; - procedure SetColor(const aColor: TtsColor4f); override; - procedure Render(const aCharRef: TtsCharRenderRef; const aForcedWidth: Integer = 0); override; - public - // TODO destructor Destroy; override; - end; - } - - TtsRendererHashSet = specialize TutlHashSet; - -var - IsInitilized: Boolean = false; - Contexts: TtsContextHashSet = nil; - Renderers: TtsRendererHashSet = nil; - LastErrorCode: TltsErrorCode = ltsErrNone; - LastErrorMsg: String; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//helper methods//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -procedure SetLastError(const aEx: Exception); -begin - LastErrorCode := ltsErrUnknown; - LastErrorMsg := aEx.Message; -end; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -procedure SetLastError(const aErrorCode: TltsErrorCode; const aErrorMsg: String); -begin - LastErrorCode := aErrorCode; - LastErrorMsg := aErrorMsg; -end; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -function CheckIfInitialized: Boolean; -begin - result := IsInitilized; - if not result then - SetLastError(ltsErrNotInitialized, 'libTextSuite has not been initialized. call ltsInitialize before using any other methods.'); -end; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -function CheckContextHandle(const aHandle: TltsContextHandle; out aContext: TtsContext): Boolean; -begin - result := CheckIfInitialized; - if result then begin - aContext := TltsContext(aHandle); - result := Contexts.Contains(aContext); - if not result then - SetLastError(ltsErrInvalidContextHandle, Format('0x%.16x is not a valid context handle', [{%H-}PtrUInt(aHandle)])); - end; -end; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -function CheckRendererHandle(const aHandle: TltsContextHandle; out aRenderer: TtsRenderer): Boolean; -begin - result := CheckIfInitialized; - if result then begin - aRenderer := TtsRenderer(aHandle); - result := Renderers.Contains(aRenderer); - if not result then - SetLastError(ltsErrInvalidRendererHandle, Format('0x%.16x is not a valid renderer handle', [{%H-}PtrUInt(aHandle)])); - end; -end; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -function ValidateCodePage(const aValue: TtsCodePage): Boolean; -begin - result := (aValue >= Low(TtsCodePage)) and (aValue <= High(TtsCodePage)); -end; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -function ValidateFormat(const aValue: TtsFormat): Boolean; -begin - result := (aValue >= Low(TtsFormat)) and (aValue <= High(TtsFormat)); -end; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//Context/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -function ltsContextCreate: TltsContextHandle; stdcall; -var - c: TltsContext; -begin - try - result := nil; - if not CheckIfInitialized then - exit; - c := TltsContext.Create; - Contexts.Add(c); - result := c; - except - on ex: Exception do begin - SetLastError(ex); - result := nil; - end; - end; -end; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -function ltsContextGetCodePage(const aHandle: TltsContextHandle; var aCodePage: TtsCodePage): TltsErrorCode; stdcall; -var - c: TtsContext; -begin - try - result := ltsErrNone; - if CheckContextHandle(aHandle, c) - then aCodePage := c.CodePage - else result := LastErrorCode; - except - on ex: Exception do begin - SetLastError(ex); - result := LastErrorCode; - end; - end; -end; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -function ltsContextGetDefaultChar(const aHandle: TltsContextHandle; var aValue: WideChar): TltsErrorCode; stdcall; -var - c: TtsContext; -begin - try - result := ltsErrNone; - if CheckContextHandle(aHandle, c) - then aValue := c.CodePageDefault - else result := LastErrorCode; - except - on ex: Exception do begin - SetLastError(ex); - result := LastErrorCode; - end; - end; -end; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -function ltsContextSetCodePage(const aHandle: TltsContextHandle; const aCodePage: TtsCodePage): TltsErrorCode; stdcall; -var - c: TtsContext; -begin - try - result := ltsErrNone; - if CheckContextHandle(aHandle, c) then begin - if not ValidateCodePage(aCodePage) then begin - SetLastError(ltsErrInvalidEnum, Format('%d is not a valid enum value for CodePage', [aCodePage])); - result := LastErrorCode; - end else - c.CodePage := aCodePage; - end else - result := LastErrorCode; - except - on ex: Exception do begin - SetLastError(ex); - result := LastErrorCode; - end; - end; -end; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -function ltsContextSetDefaultChar(const aHandle: TltsContextHandle; const aValue: WideChar): TltsErrorCode; stdcall; -var - c: TtsContext; -begin - try - result := ltsErrNone; - if CheckContextHandle(aHandle, c) - then c.CodePageDefault := aValue - else result := LastErrorCode; - except - on ex: Exception do begin - SetLastError(ex); - result := LastErrorCode; - end; - end; -end; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -function ltsContextDestroy(const aHandle: TltsContextHandle): TltsErrorCode; stdcall; -var - c: TtsContext; -begin - try - result := ltsErrNone; - if CheckContextHandle(aHandle, c) - then Contexts.Remove(c) - else result := LastErrorCode; - except - on ex: Exception do begin - SetLastError(ex); - result := LastErrorCode; - end; - end; -end; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//Renderer////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -function ltsRendererCreate(const aHandle: TltsContextHandle; const aType: TltsRendererType; const aFormat: TtsFormat): TltsRendererHandle; stdcall; -var - c: TtsContext; - r: TtsRenderer; -begin - try - result := nil; - if not CheckContextHandle(aHandle, c) then - exit; - - if not ValidateFormat(aFormat) then begin - SetLastError(ltsErrInvalidEnum, Format('%d is not a valid format', [aFormat])); - exit; - end; - - case aType of - ltsRendererOpenGL: r := TltsRendererOpenGL.Create(c, aFormat); - ltsRendererOpenGLES: r := TltsRendererOpenGLES.Create(c, aFormat); - // TODO ltsRendererCustom: r := TltsRendererCustom.Create(c, aFormat); - else - SetLastError(ltsErrInvalidEnum, Format('%d is not a valid renderer type', [aType])); - exit; - end; - Renderers.Add(r); - result := r; - except - on ex: Exception do begin - SetLastError(ex); - result := nil; - end; - end; -end; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -function ltsRendererDestroy(const aHandle: TltsRendererHandle): TltsErrorCode; stdcall; -var - r: TtsRenderer; -begin - try - result := ltsErrNone; - if CheckRendererHandle(aHandle, r) - then Renderers.Remove(r) - else result := LastErrorCode; - except - on ex: Exception do begin - SetLastError(ex); - result := LastErrorCode; - end; - end; -end; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//Global//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -function ltsInitialize: TltsErrorCode; stdcall; -begin - try - Contexts := TtsContextHashSet.Create(true); - Renderers := TtsRendererHashSet.Create(true); - IsInitilized := true; - result := ltsErrNone; - except - on ex: Exception do begin - SetLastError(ex); - result := LastErrorCode; - end; - end; -end; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -function ltsGetLastErrorCode: TltsErrorCode; stdcall; -begin - result := LastErrorCode; -end; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -function ltsGetLastErrorMsg: PAnsiChar; stdcall; -begin - result := PAnsiChar(LastErrorMsg); -end; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -function ltsFinalize: TltsErrorCode; stdcall; -begin - try - IsInitilized := false; - FreeAndNil(Renderers); - FreeAndNil(Contexts); - result := ltsErrNone; - except - on ex: Exception do begin - SetLastError(ex); - result := LastErrorCode; - end; - end; -end; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// exports ltsContextCreate, ltsContextGetCodePage, @@ -372,27 +15,97 @@ exports ltsContextDestroy, ltsRendererCreate, + ltsRendererBeginBlock, + ltsRendererEndBlock, ltsRendererDestroy, + ltsFontCreatorCreate, + ltsFontCreatorGetFontByName, + ltsFontCreatorGetFontByFile, + ltsFontCreatorGetFontByStream, + ltsFontCreatorDestroy, + + ltsFontGetPostProcessor, + ltsFontGetTabWidth, + ltsFontGetCharSpacing, + ltsFontGetLineSpacing, + ltsFontGetMetric, + ltsFontGetFontname, + ltsFontGetFacename, + ltsFontGetStylename, + ltsFontGetFullname, + ltsFontGetCopyright, + ltsFontSetPostProcessor, + ltsFontSetTabWidth, + ltsFontSetCharSpacing, + ltsFontSetLineSpacing, + + ltsTextBlockGetRect, + ltsTextBlockGetWidth, + ltsTextBlockGetHeight, + ltsTextBlockGetFlags, + ltsTextBlockGetTop, + ltsTextBlockGetLeft, + ltsTextBlockGetVertAlign, + ltsTextBlockGetHorzAlign, + ltsTextBlockGetClipping, + ltsTextBlockGetColor, + ltsTextBlockGetFont, + ltsTextBlockSetTop, + ltsTextBlockSetLeft, + ltsTextBlockSetVertAlign, + ltsTextBlockSetHorzAlign, + ltsTextBlockSetClipping, + ltsTextBlockSetColor, + ltsTextBlockSetFont, + ltsTextBlockGetActualHeight, + ltsTextBlockGetTextWidthA, + ltsTextBlockGetTextWidthW, + ltsTextBlockTextOutA, + ltsTextBlockTextOutW, + + ltsImageCreate, + ltsImageIsEmpty, + ltsImageGetWidth, + ltsImageGetHeight, + ltsImageGetLineSize, + ltsImageGetDataSize, + ltsImageGetFormat, + ltsImageGetData, + ltsImageGetScanline, + lstImageGetPixelAt, + ltsImageAssign, + ltsImageCreateEmpty, + ltsImageLoadFromFunc, + ltsImageResize, + ltsImageFillColor, + ltsImageFillPattern, + ltsImageBlend, + ltsImageBlur, + ltsImageDestroy, + + ltsPostProcessorAddRange, + ltsPostProcessorAddChars, + ltsPostProcessorClearRanges, + ltsPostProcessorFillColorCreate, + ltsPostProcessorFillPatterCreate, + ltsPostProcessorBorderCreate, + ltsPostProcessorShadowCreate, + ltsPostProcessorListCreate, + ltsPostProcessorListGetCount, + ltsPostProcessorListGetItem, + ltsPostProcessorListGetOwnsObjects, + ltsPostProcessorListSetOwnsObjects, + ltsPostProcessorListAdd, + ltsPostProcessorListDel, + ltsPostProcessorListClear, + ltsPostProcessorListRem, + ltsPostProcessorListIndexOf, + ltsInitialize, ltsGetLastErrorCode, ltsGetLastErrorMsg, ltsFinalize; -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//TltsContext/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -destructor TltsContext.Destroy; -var - i: Integer; -begin - if Assigned(Renderers) then begin - for i := fRenderers.Count-1 downto 0 do - Renderers.Remove(fRenderers[i] as TtsRenderer); - end; - // TODO cleanup generators - inherited Destroy; -end; - end. diff --git a/ultsContext.pas b/ultsContext.pas new file mode 100644 index 0000000..4ed1dac --- /dev/null +++ b/ultsContext.pas @@ -0,0 +1,187 @@ +unit ultsContext; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, + utsTextSuite, utsUtils, + ultsTypes; + +type +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TltsContext = class(TtsContext) + public + procedure DelSlave(const aSlave: TtsRefManager); override; + end; + + function ltsContextCreate (): TltsContextHandle; stdcall; + function ltsContextGetCodePage (const aHandle: TltsContextHandle; var aCodePage: TtsCodePage): TltsErrorCode; stdcall; + function ltsContextGetDefaultChar (const aHandle: TltsContextHandle; var aValue: WideChar): TltsErrorCode; stdcall; + function ltsContextSetCodePage (const aHandle: TltsContextHandle; const aCodePage: TtsCodePage): TltsErrorCode; stdcall; + function ltsContextSetDefaultChar (const aHandle: TltsContextHandle; const aValue: WideChar): TltsErrorCode; stdcall; + function ltsContextAnsiToWide (const aHandle: TltsContextHandle; const aText: PAnsiChar): PWideChar; stdcall; + function ltsContextDestroy (const aHandle: TltsContextHandle): TltsErrorCode; stdcall; + +implementation + +uses + ultsUtils; + +var + WideStringBuffer: WideString; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//TltsContext/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TltsContext.DelSlave(const aSlave: TtsRefManager); +begin + DelReference(aSlave); + inherited DelSlave(aSlave); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//Context/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsContextCreate: TltsContextHandle; stdcall; +var + c: TltsContext; +begin + try + result := nil; + if not CheckIfInitialized then + exit; + c := TltsContext.Create; + AddReference(ltsObjTypeContext, c); + result := c; + except + on ex: Exception do begin + SetLastError(ex); + result := nil; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsContextGetCodePage(const aHandle: TltsContextHandle; var aCodePage: TtsCodePage): TltsErrorCode; stdcall; +var + c: TtsContext; +begin + try + result := ltsErrNone; + if CheckContextHandle(aHandle, c) + then aCodePage := c.CodePage + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsContextGetDefaultChar(const aHandle: TltsContextHandle; var aValue: WideChar): TltsErrorCode; stdcall; +var + c: TtsContext; +begin + try + result := ltsErrNone; + if CheckContextHandle(aHandle, c) + then aValue := c.DefaultChar + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsContextSetCodePage(const aHandle: TltsContextHandle; const aCodePage: TtsCodePage): TltsErrorCode; stdcall; +var + c: TtsContext; +begin + try + result := ltsErrNone; + if CheckContextHandle(aHandle, c) then begin + if not ValidateCodePage(aCodePage) then begin + SetLastError(ltsErrInvalidEnum, Format('%d is not a valid enum value for CodePage', [aCodePage])); + result := LastErrorCode; + end else + c.CodePage := aCodePage; + end else + result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsContextSetDefaultChar(const aHandle: TltsContextHandle; const aValue: WideChar): TltsErrorCode; stdcall; +var + c: TtsContext; +begin + try + result := ltsErrNone; + if CheckContextHandle(aHandle, c) + then c.DefaultChar := aValue + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsContextAnsiToWide(const aHandle: TltsContextHandle; const aText: PAnsiChar): PWideChar; stdcall; +var + c: TtsContext; + w: PWideChar; +begin + try + result := nil; + if CheckContextHandle(aHandle, c) then begin + w := c.AnsiToWide(aText); + if not Assigned(w) then + exit; + WideStringBuffer := w; + tsStrDispose(w); + result := PWideChar(WideStringBuffer); + end else + result := nil; + except + on ex: Exception do begin + SetLastError(ex); + result := nil; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsContextDestroy(const aHandle: TltsContextHandle): TltsErrorCode; stdcall; +var + c: TtsContext; +begin + try + result := ltsErrNone; + if CheckContextHandle(aHandle, c) + then DelReference(ltsObjTypeContext, c) + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +end. + diff --git a/ultsFont.pas b/ultsFont.pas new file mode 100644 index 0000000..5591de7 --- /dev/null +++ b/ultsFont.pas @@ -0,0 +1,284 @@ +unit ultsFont; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, + utsTextSuite, + ultsTypes; + +function ltsFontGetPostProcessor (const aHandle: TltsFontHandle): TltsPostProcessorHandle; stdcall; +function ltsFontGetTabWidth (const aHandle: TltsFontHandle; var aValue: Integer): TltsErrorCode; stdcall; +function ltsFontGetCharSpacing (const aHandle: TltsFontHandle; var aValue: Integer): TltsErrorCode; stdcall; +function ltsFontGetLineSpacing (const aHandle: TltsFontHandle; var aValue: Single): TltsErrorCode; stdcall; +function ltsFontGetMetric (const aHandle: TltsFontHandle; var aValue: TtsFontMetric): TltsErrorCode; stdcall; + +function ltsFontGetFontname (const aHandle: TltsFontHandle): PAnsiChar; stdcall; +function ltsFontGetFacename (const aHandle: TltsFontHandle): PAnsiChar; stdcall; +function ltsFontGetStylename (const aHandle: TltsFontHandle): PAnsiChar; stdcall; +function ltsFontGetFullname (const aHandle: TltsFontHandle): PAnsiChar; stdcall; +function ltsFontGetCopyright (const aHandle: TltsFontHandle): PAnsiChar; stdcall; + +function ltsFontSetPostProcessor (const aHandle: TltsFontHandle; const aValue: TltsPostProcessorHandle): TltsErrorCode; stdcall; +function ltsFontSetTabWidth (const aHandle: TltsFontHandle; const aValue: Integer): TltsErrorCode; stdcall; +function ltsFontSetCharSpacing (const aHandle: TltsFontHandle; const aValue: Integer): TltsErrorCode; stdcall; +function ltsFontSetLineSpacing (const aHandle: TltsFontHandle; const aValue: Single): TltsErrorCode; stdcall; + +implementation + +uses + ultsUtils; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//Font////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsFontGetPostProcessor(const aHandle: TltsFontHandle): TltsPostProcessorHandle; stdcall; +var + f: TtsFont; +begin + try + if CheckFontHandle(aHandle, f) + then result := f.PostProcessor + else result := nil; + except + on ex: Exception do begin + SetLastError(ex); + result := nil; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsFontGetTabWidth(const aHandle: TltsFontHandle; var aValue: Integer): TltsErrorCode; stdcall; +var + f: TtsFont; +begin + try + result := ltsErrNone; + if CheckFontHandle(aHandle, f) + then aValue := f.TabWidth + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsFontGetCharSpacing(const aHandle: TltsFontHandle; var aValue: Integer): TltsErrorCode; stdcall; +var + f: TtsFont; +begin + try + result := ltsErrNone; + if CheckFontHandle(aHandle, f) + then aValue := f.CharSpacing + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsFontGetLineSpacing(const aHandle: TltsFontHandle; var aValue: Single): TltsErrorCode; stdcall; +var + f: TtsFont; +begin + try + result := ltsErrNone; + if CheckFontHandle(aHandle, f) + then aValue := f.LineSpacing + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsFontGetMetric(const aHandle: TltsFontHandle; var aValue: TtsFontMetric): TltsErrorCode; stdcall; +var + f: TtsFont; +begin + try + result := ltsErrNone; + if CheckFontHandle(aHandle, f) + then aValue := f.Metric + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsFontGetFontname(const aHandle: TltsFontHandle): PAnsiChar; stdcall; +var + f: TtsFont; +begin + try + if CheckFontHandle(aHandle, f) + then result := PAnsiChar(f.Names.Fontname) + else result := nil; + except + on ex: Exception do begin + SetLastError(ex); + result := nil; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsFontGetFacename(const aHandle: TltsFontHandle): PAnsiChar; stdcall; +var + f: TtsFont; +begin + try + if CheckFontHandle(aHandle, f) + then result := PAnsiChar(f.Names.FaceName) + else result := nil; + except + on ex: Exception do begin + SetLastError(ex); + result := nil; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsFontGetStylename(const aHandle: TltsFontHandle): PAnsiChar; stdcall; +var + f: TtsFont; +begin + try + if CheckFontHandle(aHandle, f) + then result := PAnsiChar(f.Names.StyleName) + else result := nil; + except + on ex: Exception do begin + SetLastError(ex); + result := nil; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsFontGetFullname(const aHandle: TltsFontHandle): PAnsiChar; stdcall; +var + f: TtsFont; +begin + try + if CheckFontHandle(aHandle, f) + then result := PAnsiChar(f.Names.FullName) + else result := nil; + except + on ex: Exception do begin + SetLastError(ex); + result := nil; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsFontGetCopyright(const aHandle: TltsFontHandle): PAnsiChar; stdcall; +var + f: TtsFont; +begin + try + if CheckFontHandle(aHandle, f) + then result := PAnsiChar(f.Names.Copyright) + else result := nil; + except + on ex: Exception do begin + SetLastError(ex); + result := nil; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsFontSetPostProcessor(const aHandle: TltsFontHandle; const aValue: TltsPostProcessorHandle): TltsErrorCode; stdcall; +var + f: TtsFont; + p: TtsPostProcessor; +begin + try + result := ltsErrNone; + if CheckFontHandle(aHandle, f) and CheckPostProcessorHandle(aValue, TtsPostProcessor, p) + then f.PostProcessor := p + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsFontSetTabWidth(const aHandle: TltsFontHandle; const aValue: Integer): TltsErrorCode; stdcall; +var + f: TtsFont; +begin + try + result := ltsErrNone; + if CheckFontHandle(aHandle, f) + then f.TabWidth := aValue + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsFontSetCharSpacing(const aHandle: TltsFontHandle; const aValue: Integer): TltsErrorCode; stdcall; +var + f: TtsFont; +begin + try + result := ltsErrNone; + if CheckFontHandle(aHandle, f) + then f.CharSpacing := aValue + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsFontSetLineSpacing(const aHandle: TltsFontHandle; const aValue: Single): TltsErrorCode; stdcall; +var + f: TtsFont; +begin + try + result := ltsErrNone; + if CheckFontHandle(aHandle, f) + then f.LineSpacing := aValue + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +end. + diff --git a/ultsFontCreator.pas b/ultsFontCreator.pas new file mode 100644 index 0000000..edcf54a --- /dev/null +++ b/ultsFontCreator.pas @@ -0,0 +1,196 @@ +unit ultsFontCreator; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, + utsTextSuite, + ultsTypes; + +function ltsFontCreatorCreate (const aHandle: TltsContextHandle; const aType: TltsFontCreatorType): TltsFontCreatorHandle; stdcall; +function ltsFontCreatorGetFontByName (const aHandle: TltsFontCreatorHandle; const aFontname: PAnsiChar; const aSize: Integer; + const aStyle: TtsFontStyles; const aAntiAliasing: TtsAntiAliasing): TltsFontHandle; stdcall; +function ltsFontCreatorGetFontByFile (const aHandle: TltsFontCreatorHandle; const aFilename: PAnsiChar; const aSize: Integer; + const aStyle: TtsFontStyles; const aAntiAliasing: TtsAntiAliasing): TltsFontHandle; stdcall; +function ltsFontCreatorGetFontByStream(const aHandle: TltsFontCreatorHandle; const aStream: PltsStream; const aSize: Integer; + const aStyle: TtsFontStyles; const aAntiAliasing: TtsAntiAliasing): TltsFontHandle; stdcall; +function ltsFontCreatorDestroy (const aHandle: TltsFontCreatorHandle): TltsErrorCode; stdcall; + +implementation + +uses + utsUtils, + ultsUtils; + +type +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TltsFontCreatorFreeType = class(TtsFontCreatorFreeType) + public + procedure DelSlave(const aSlave: TtsRefManager); override; + end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TltsFontCreatorGDI = class(TtsFontCreatorGDI) + public + procedure DelSlave(const aSlave: TtsRefManager); override; + end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//TltsFontCreatorFreeType/////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TltsFontCreatorFreeType.DelSlave(const aSlave: TtsRefManager); +begin + DelReference(aSlave); + inherited DelSlave(aSlave); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//TltsFontCreatorGDI//////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TltsFontCreatorGDI.DelSlave(const aSlave: TtsRefManager); +begin + DelReference(aSlave); + inherited DelSlave(aSlave); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//FontCreato/////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsFontCreatorCreate(const aHandle: TltsContextHandle; const aType: TltsFontCreatorType): TltsFontCreatorHandle; stdcall; +var + c: TtsContext; + fc: TtsFontCreator; +begin + try + result := nil; + if not CheckContextHandle(aHandle, c) then + exit; + + case aType of + ltsFontCreatorFreeType: fc := TltsFontCreatorFreeType.Create(c); + ltsFontCreatorGDI: fc := TltsFontCreatorGDI.Create(c); + // TODO ltsRendererCustom: r := TltsRendererCustom.Create(c, aFormat); + else + SetLastError(ltsErrInvalidEnum, Format('%d is not a valid font creator type', [aType])); + exit; + end; + AddReference(ltsObjTypeFontCreator, fc); + result := fc; + except + on ex: Exception do begin + SetLastError(ex); + result := nil; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsFontCreatorGetFontByName(const aHandle: TltsFontCreatorHandle; const aFontname: PAnsiChar; + const aSize: Integer; const aStyle: TtsFontStyles; const aAntiAliasing: TtsAntiAliasing): TltsFontHandle; stdcall; +var + fc: TtsFontCreator; + f: TtsFont; +begin + try + result := nil; + if not CheckFontCreatorHandle(aHandle, fc) then + exit; + f := fc.GetFontByName(aFontname, aSize, aStyle, aAntiAliasing); + if not Assigned(f) then begin + SetLastError(ltsErrInvalidOperation, 'GetFontByName is not supported by this font creator'); + exit; + end; + AddReference(ltsObjTypeFont, f); + result := f; + except + on ex: Exception do begin + SetLastError(ex); + result := nil; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsFontCreatorGetFontByFile(const aHandle: TltsFontCreatorHandle; const aFilename: PAnsiChar; + const aSize: Integer; const aStyle: TtsFontStyles; const aAntiAliasing: TtsAntiAliasing): TltsFontHandle; stdcall; +var + fc: TtsFontCreator; + f: TtsFont; +begin + try + result := nil; + if not CheckFontCreatorHandle(aHandle, fc) then + exit; + f := fc.GetFontByFile(aFilename, aSize, aStyle, aAntiAliasing); + if not Assigned(f) then begin + SetLastError(ltsErrInvalidOperation, 'GetFontByFile is not supported by this font creator'); + exit; + end; + AddReference(ltsObjTypeFont, f); + result := f; + except + on ex: Exception do begin + SetLastError(ex); + result := nil; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsFontCreatorGetFontByStream(const aHandle: TltsFontCreatorHandle; const aStream: PltsStream; + const aSize: Integer; const aStyle: TtsFontStyles; const aAntiAliasing: TtsAntiAliasing): TltsFontHandle; stdcall; +var + fc: TtsFontCreator; + f: TtsFont; + s: TStream; +begin + try + result := nil; + if not CheckFontCreatorHandle(aHandle, fc) then + exit; + + s := TltsStreamImpl.Create(aStream); + try + f := fc.GetFontByStream(s, aSize, aStyle, aAntiAliasing); + finally + FreeAndNil(s); + end; + + if not Assigned(f) then begin + SetLastError(ltsErrInvalidOperation, 'GetFontByStream is not supported by this font creator'); + exit; + end; + AddReference(ltsObjTypeFont, f); + result := f; + except + on ex: Exception do begin + SetLastError(ex); + result := nil; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsFontCreatorDestroy(const aHandle: TltsFontCreatorHandle): TltsErrorCode; stdcall; +var + fc: TtsFontCreator; +begin + try + result := ltsErrNone; + if CheckFontCreatorHandle(aHandle, fc) then begin + DelReference(ltsObjTypeFontCreator, fc); + FreeAndNil(fc); + end else + result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +end. + diff --git a/ultsGeneral.pas b/ultsGeneral.pas new file mode 100644 index 0000000..ed0db8e --- /dev/null +++ b/ultsGeneral.pas @@ -0,0 +1,64 @@ +unit ultsGeneral; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, + ultsTypes; + +function ltsInitialize: TltsErrorCode; stdcall; +function ltsGetLastErrorCode: TltsErrorCode; stdcall; +function ltsGetLastErrorMsg: PAnsiChar; stdcall; +function ltsFinalize: TltsErrorCode; stdcall; + +implementation + +uses + ultsUtils; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//General/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsInitialize: TltsErrorCode; stdcall; +begin + try + result := ltsErrNone; + Initialize; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsGetLastErrorCode: TltsErrorCode; stdcall; +begin + result := LastErrorCode; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsGetLastErrorMsg: PAnsiChar; stdcall; +begin + result := PAnsiChar(LastErrorMsg); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsFinalize: TltsErrorCode; stdcall; +begin + try + Finalize; + result := ltsErrNone; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +end. + diff --git a/ultsImage.pas b/ultsImage.pas new file mode 100644 index 0000000..4db6c5a --- /dev/null +++ b/ultsImage.pas @@ -0,0 +1,458 @@ +unit ultsImage; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, + utsTextSuite, + ultsTypes; + +type + TltsImageFunc = procedure(const aHandle: TltsImageHandle; const X, Y: Integer; var aPixel: TtsColor4f; aArgs: Pointer); stdcall; + TltsBlendColorFunc = function (const aHandle: TltsImageHandle; const aSrc, aDst: TtsColor4f; aArgs: Pointer): TtsColor4f; stdcall; + +function ltsImageCreate (const aContext: TltsContextHandle): TltsImageHandle; stdcall; +function ltsImageIsEmpty (const aHandle: TltsImageHandle; var aValue: Boolean): TltsErrorCode; stdcall; +function ltsImageGetWidth (const aHandle: TltsImageHandle): Integer; stdcall; +function ltsImageGetHeight (const aHandle: TltsImageHandle): Integer; stdcall; +function ltsImageGetLineSize (const aHandle: TltsImageHandle): Integer; stdcall; +function ltsImageGetDataSize (const aHandle: TltsImageHandle): Integer; stdcall; +function ltsImageGetFormat (const aHandle: TltsImageHandle; var aValue: TtsFormat): TltsErrorCode; stdcall; +function ltsImageGetData (const aHandle: TltsImageHandle): Pointer; stdcall; +function ltsImageGetScanline (const aHandle: TltsImageHandle; const aIndex: Integer): Pointer; stdcall; +function lstImageGetPixelAt (const aHandle: TltsImageHandle; const aX, aY: Integer; var aColor: TtsColor4f): TltsErrorCode; stdcall; +function ltsImageAssign (const aHandle, aSource: TltsImageHandle): TltsErrorCode; stdcall; +function ltsImageCreateEmpty (const aHandle: TltsImageHandle; const aFormat: TtsFormat; const aWidth, aHeight: Integer): TltsErrorCode; stdcall; +function ltsImageLoadFromFunc (const aHandle: TltsImageHandle; const aCallback: TltsImageFunc; aArgs: Pointer): TltsErrorCode; stdcall; +function ltsImageResize (const aHandle: TltsImageHandle; const aWidth, aHeight, aX, aY: Integer): TltsErrorCode; stdcall; +function ltsImageFillColor (const aHandle: TltsImageHandle; const aColor: TtsColor4f; const aMask: TtsColorChannels; const aModes: TtsImageModes): TltsErrorCode; stdcall; +function ltsImageFillPattern (const aHandle, aPattern: TltsImageHandle; const aX, aY: Integer; const aMask: TtsColorChannels; const aModes: TtsImageModes): TltsErrorCode; stdcall; +function ltsImageBlend (const aHandle, aSource: TltsImageHandle; const aX, aY: Integer; const aBlendFunc: TltsBlendColorFunc; aArgs: Pointer): TltsErrorCode; stdcall; +function ltsImageBlur (const aHandle: TltsImageHandle; const aHorzRad, aHorzStr, aVertRad, aVertStr: Single; const aMask: TtsColorChannels): TltsErrorCode; stdcall; +function ltsImageDestroy (const aHandle: TltsImageHandle): TltsErrorCode; stdcall; + +implementation + +uses + ultsUtils, utsUtils; + +type + PLoadArgs = ^TLoadArgs; + TLoadArgs = packed record + args: Pointer; + handle: TltsImageHandle; + callback: TltsImageFunc + end; + + PBlendArgs = ^TBlendArgs; + TBlendArgs = packed record + args: Pointer; + handle: TltsImageHandle; + callback: TltsBlendColorFunc; + end; + +procedure ImageLoadCallback(const aImage: TtsImage; X, Y: Integer; var aPixel: TtsColor4f; aArgs: Pointer); +var + p: PLoadArgs; +begin + p := PLoadArgs(aArgs); + p^.callback(p^.handle, X, Y, aPixel, p^.args); +end; + +function ImageBlendCallback(const aSrc, aDst: TtsColor4f; aArgs: Pointer): TtsColor4f; +var + p: PBlendArgs; +begin + p := PBlendArgs(aArgs); + result := p^.callback(p^.handle, aSrc, aDst, p^.args); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//ltsImage////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsImageCreate(const aContext: TltsContextHandle): TltsImageHandle; stdcall; +var + img: TtsImage; + c: TtsContext; +begin + try + result := nil; + if not CheckContextHandle(aContext, c) then + exit; + img := TtsImage.Create(c); + AddReference(ltsObjTypeImage, img); + result := img; + except + on ex: Exception do begin + SetLastError(ex); + result := nil; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsImageIsEmpty(const aHandle: TltsImageHandle; var aValue: Boolean): TltsErrorCode; stdcall; +var + img: TtsImage; +begin + try + result := ltsErrNone; + if CheckImageHandle(aHandle, img) + then aValue := img.IsEmpty + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsImageGetWidth(const aHandle: TltsImageHandle): Integer; stdcall; +var + img: TtsImage; +begin + try + if CheckImageHandle(aHandle, img) + then result := img.Width + else result := -1; + except + on ex: Exception do begin + SetLastError(ex); + result := -1; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsImageGetHeight(const aHandle: TltsImageHandle): Integer; stdcall; +var + img: TtsImage; +begin + try + if CheckImageHandle(aHandle, img) + then result := img.Height + else result := -1; + except + on ex: Exception do begin + SetLastError(ex); + result := -1; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsImageGetLineSize(const aHandle: TltsImageHandle): Integer; stdcall; +var + img: TtsImage; +begin + try + if CheckImageHandle(aHandle, img) + then result := img.LineSize + else result := -1; + except + on ex: Exception do begin + SetLastError(ex); + result := -1; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsImageGetDataSize(const aHandle: TltsImageHandle): Integer; stdcall; +var + img: TtsImage; +begin + try + if CheckImageHandle(aHandle, img) + then result := img.DataSize + else result := -1; + except + on ex: Exception do begin + SetLastError(ex); + result := -1; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsImageGetFormat(const aHandle: TltsImageHandle; var aValue: TtsFormat): TltsErrorCode; stdcall; +var + img: TtsImage; +begin + try + result := ltsErrNone; + if CheckImageHandle(aHandle, img) + then aValue := img.Format + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsImageGetData(const aHandle: TltsImageHandle): Pointer; stdcall; +var + img: TtsImage; +begin + try + if CheckImageHandle(aHandle, img) + then result := img.Data + else result := nil; + except + on ex: Exception do begin + SetLastError(ex); + result := nil; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsImageGetScanline(const aHandle: TltsImageHandle; const aIndex: Integer): Pointer; stdcall; +var + img: TtsImage; +begin + try + if CheckImageHandle(aHandle, img) then begin + result := img.Scanline[aIndex]; + if not Assigned(result) then + SetLastError(ltsErrInvalidValue, Format('index (%d) is out of range', [aIndex])); + end else + result := nil; + except + on ex: Exception do begin + SetLastError(ex); + result := nil; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function lstImageGetPixelAt(const aHandle: TltsImageHandle; const aX, aY: Integer; var aColor: TtsColor4f): TltsErrorCode; stdcall; +var + img: TtsImage; +begin + try + result := ltsErrNone; + if CheckImageHandle(aHandle, img) then begin + if not img.GetPixelAt(aX, aY, aColor) then begin + SetLastError(ltsErrInvalidValue, Format('x (%d) or y (%d) is out of range', [aX, aY])); + result := LastErrorCode; + end; + end else + result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsImageAssign(const aHandle, aSource: TltsImageHandle): TltsErrorCode; stdcall; +var + img, src: TtsImage; +begin + try + result := ltsErrNone; + if CheckImageHandle(aHandle, img) and CheckImageHandle(aSource, src) + then img.Assign(src) + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsImageCreateEmpty(const aHandle: TltsImageHandle; const aFormat: TtsFormat; const aWidth, aHeight: Integer): TltsErrorCode; stdcall; +var + img: TtsImage; +begin + try + result := ltsErrNone; + if not ValidateFormat(aFormat) then begin + result := LastErrorCode; + end else if (aWidth < 0) then begin + SetLastError(ltsErrInvalidValue, 'width must be a positive value'); + result := LastErrorCode; + end else if (aHeight < 0) then begin + SetLastError(ltsErrInvalidValue, 'height must be a positive value'); + result := LastErrorCode; + end else if not CheckImageHandle(aHandle, img) then begin + result := LastErrorCode; + end else + img.CreateEmpty(aFormat, aWidth, aHeight); + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsImageLoadFromFunc(const aHandle: TltsImageHandle; const aCallback: TltsImageFunc; aArgs: Pointer): TltsErrorCode; stdcall; +var + img: TtsImage; + la: TLoadArgs; +begin + try + result := ltsErrNone; + if CheckImageHandle(aHandle, img) then begin + la.args := aArgs; + la.callback := aCallback; + la.handle := aHandle; + img.LoadFromFunc(@ImageLoadCallback, @la); + end else + result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsImageResize(const aHandle: TltsImageHandle; const aWidth, aHeight, aX, aY: Integer): TltsErrorCode; stdcall; +var + img: TtsImage; +begin + try + result := ltsErrNone; + if (aWidth < 0) then begin + SetLastError(ltsErrInvalidValue, 'width must be a positive value'); + result := LastErrorCode; + end else if (aHeight < 0) then begin + SetLastError(ltsErrInvalidValue, 'height must be a positive value'); + result := LastErrorCode; + end else if not CheckImageHandle(aHandle, img) then begin + result := LastErrorCode; + end else + img.Resize(aWidth, aHeight, aX, aY); + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsImageFillColor(const aHandle: TltsImageHandle; const aColor: TtsColor4f; const aMask: TtsColorChannels; const aModes: TtsImageModes): TltsErrorCode; stdcall; +var + img: TtsImage; +begin + try + result := ltsErrNone; + if CheckImageHandle(aHandle, img) + then img.FillColor(aColor, aMask, aModes) + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsImageFillPattern(const aHandle, aPattern: TltsImageHandle; const aX, aY: Integer; const aMask: TtsColorChannels; const aModes: TtsImageModes): TltsErrorCode; stdcall; +var + img, pattern: TtsImage; +begin + try + result := ltsErrNone; + if CheckImageHandle(aHandle, img) and CheckImageHandle(aPattern, pattern) + then img.FillPattern(pattern, aX, aY, aMask, aModes) + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsImageBlend(const aHandle, aSource: TltsImageHandle; const aX, aY: Integer; const aBlendFunc: TltsBlendColorFunc; aArgs: Pointer): TltsErrorCode; stdcall; +var + img, src: TtsImage; + ba: TBlendArgs; +begin + try + result := ltsErrNone; + if CheckImageHandle(aHandle, img) and CheckImageHandle(aSource, src) then begin + ba.args := aArgs; + ba.handle := aHandle; + ba.callback := aBlendFunc; + img.Blend(src, aX, aY, @ImageBlendCallback, @ba); + end else + result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsImageBlur(const aHandle: TltsImageHandle; const aHorzRad, aHorzStr, aVertRad, aVertStr: Single; const aMask: TtsColorChannels): TltsErrorCode; stdcall; +var + img: TtsImage; + horz, vert: TtsKernel1D; +begin + try + result := ltsErrNone; + if CheckImageHandle(aHandle, img) then begin + horz := TtsKernel1D.Create(aHorzRad, aHorzStr); + vert := TtsKernel1D.Create(aVertRad, aVertStr); + try + img.Blur(horz, vert, aMask); + finally + FreeAndNil(horz); + FreeAndNil(vert); + end; + end else + result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsImageDestroy(const aHandle: TltsImageHandle): TltsErrorCode; stdcall; +var + img: TtsImage; +begin + try + result := ltsErrNone; + if CheckImageHandle(aHandle, img) then begin + DelReference(ltsObjTypeImage, img); + FreeAndNil(img); + end 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 new file mode 100644 index 0000000..0670c51 --- /dev/null +++ b/ultsPostProcessor.pas @@ -0,0 +1,378 @@ +unit ultsPostProcessor; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, + ultsTypes, utsTextSuite; + +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 ltsPostProcessorFillColorCreate (const aContext: TltsContextHandle; const aColor: TtsColor4f; + const aModes: TtsImageModes; const aChannels: TtsColorChannels): TltsPostProcessorHandle; stdcall; +function ltsPostProcessorFillPatterCreate (const aContext: TltsContextHandle; const aPattern: TltsImageHandle; const aOwnsPatter: Boolean; + const aPosition: TtsPosition; const aModes: TtsImageModes; const aChannels: TtsColorChannels): TltsPostProcessorHandle; stdcall; +function ltsPostProcessorBorderCreate (const aContext: TltsContextHandle; const aWidth, aStrength: Single; + 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 ltsPostProcessorListCreate (const aContext: TltsContextHandle): TltsPostProcessorHandle; stdcall; +function ltsPostProcessorListGetCount (const aHandle: TltsPostProcessorHandle): Integer; stdcall; +function ltsPostProcessorListGetItem (const aHandle: TltsPostProcessorHandle; const aIndex: Integer): TltsPostProcessorHandle; stdcall; +function ltsPostProcessorListGetOwnsObjects (const aHandle: TltsPostProcessorHandle; var aValue: Boolean): TltsErrorCode; stdcall; +function ltsPostProcessorListSetOwnsObjects (const aHandle: TltsPostProcessorHandle; const aValue: Boolean): TltsErrorCode; stdcall; +function ltsPostProcessorListAdd (const aHandle, aItem: TltsPostProcessorHandle): TltsErrorCode; stdcall; +function ltsPostProcessorListDel (const aHandle: TltsPostProcessorHandle; const aIndex: Integer): TltsErrorCode; stdcall; +function ltsPostProcessorListClear (const aHandle: TltsPostProcessorHandle): TltsErrorCode; stdcall; +function ltsPostProcessorListRem (const aHandle, aItem: TltsPostProcessorHandle): Integer; stdcall; +function ltsPostProcessorListIndexOf (const aHandle, aItem: TltsPostProcessorHandle): Integer; stdcall; + +implementation + +uses + ultsUtils; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//ltsPostProcessor////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsPostProcessorAddRange(const aHandle: TltsPostProcessorHandle; const aUsage: TtsCharRangeUsage; const aStart, aStop: WideChar): TltsErrorCode; stdcall; +var + pp: TtsPostProcessor; +begin + try + result := ltsErrNone; + if ValidateCharRangeUsage(aUsage) and CheckPostProcessorHandle(aHandle, TtsPostProcessor, pp) + then pp.AddRange(aUsage, aStart, aStop) + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsPostProcessorAddChars(const aHandle: TltsPostProcessorHandle; const aUsage: TtsCharRangeUsage; const aChars: PWideChar): TltsErrorCode; stdcall; +var + pp: TtsPostProcessor; +begin + try + result := ltsErrNone; + if ValidateCharRangeUsage(aUsage) and CheckPostProcessorHandle(aHandle, TtsPostProcessor, pp) + then pp.AddChars(aUsage, aChars) + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsPostProcessorClearRanges(const aHandle: TltsPostProcessorHandle): TltsErrorCode; stdcall; +var + pp: TtsPostProcessor; +begin + try + result := ltsErrNone; + if CheckPostProcessorHandle(aHandle, TtsPostProcessor, pp) + then pp.ClearRanges + 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 + c: TtsContext; + pp: TtsPostProcessor; +begin + try + result := nil; + if CheckContextHandle(aContext, c) then begin + pp := TtsPostProcessorFillColor.Create(c, aColor, aModes, aChannels); + AddReference(ltsObjTypePostProcessor, pp); + result := pp; + end; + except + on ex: Exception do begin + SetLastError(ex); + result := nil; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsPostProcessorFillPatterCreate(const aContext: TltsContextHandle; const aPattern: TltsImageHandle; const aOwnsPatter: Boolean; const aPosition: TtsPosition; const aModes: TtsImageModes; const aChannels: TtsColorChannels): TltsPostProcessorHandle; stdcall; +var + c: TtsContext; + img: TtsImage; + pp: TtsPostProcessor; +begin + try + result := nil; + img := nil; + if CheckContextHandle(aContext, c) and CheckImageHandle(aPattern, img) then begin + pp := TtsPostProcessorFillPattern.Create(c, img, aOwnsPatter, aPosition, aModes, aChannels); + AddReference(ltsObjTypePostProcessor, pp); + if aOwnsPatter then + DelReference(ltsObjTypeImage, img); + result := pp; + end; + except + on ex: Exception do begin + SetLastError(ex); + result := nil; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsPostProcessorBorderCreate(const aContext: TltsContextHandle; const aWidth, aStrength: Single; const aColor: TtsColor4f; const aKeepSize: Boolean): TltsPostProcessorHandle; stdcall; +var + c: TtsContext; + pp: TtsPostProcessor; +begin + try + result := nil; + if CheckContextHandle(aContext, c) then begin + pp := TtsPostProcessorBorder.Create(c, aWidth, aStrength, aColor, aKeepSize); + AddReference(ltsObjTypePostProcessor, pp); + result := pp; + end; + except + on ex: Exception do begin + SetLastError(ex); + result := nil; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsPostProcessorShadowCreate(const aContext: TltsContextHandle; const aRadius, aStrength: Single; const aOffset: TtsPosition; const aColor: TtsColor4f): TltsPostProcessorHandle; stdcall; +var + c: TtsContext; + pp: TtsPostProcessor; +begin + try + result := nil; + if CheckContextHandle(aContext, c) then begin + pp := TtsPostProcessorShadow.Create(c, aRadius, aStrength, aOffset, aColor); + AddReference(ltsObjTypePostProcessor, pp); + result := pp; + end; + except + on ex: Exception do begin + SetLastError(ex); + result := nil; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsPostProcessorListCreate(const aContext: TltsContextHandle): TltsPostProcessorHandle; stdcall; +var + c: TtsContext; + pp: TtsPostProcessor; +begin + try + result := nil; + if CheckContextHandle(aContext, c) then begin + pp := TtsPostProcessorList.Create(c, false); + AddReference(ltsObjTypePostProcessor, pp); + result := pp; + end; + except + on ex: Exception do begin + SetLastError(ex); + result := nil; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsPostProcessorListGetCount(const aHandle: TltsPostProcessorHandle): Integer; stdcall; +var + pp: TtsPostProcessorList; +begin + try + if CheckPostProcessorHandle(aHandle, TtsPostProcessorList, pp) + then result := pp.Count + else result := -1; + except + on ex: Exception do begin + SetLastError(ex); + result := -1; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsPostProcessorListGetItem(const aHandle: TltsPostProcessorHandle; const aIndex: Integer): TltsPostProcessorHandle; stdcall; +var + pp: TtsPostProcessorList; +begin + try + result := nil; + if CheckPostProcessorHandle(aHandle, TtsPostProcessorList, pp) then begin + if (aIndex < 0) or (aIndex >= pp.Count) + then SetLastError(ltsErrInvalidValue, 'index is out of range') + else result := pp.Items[aIndex]; + end else + result := nil; + except + on ex: Exception do begin + SetLastError(ex); + result := nil; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsPostProcessorListGetOwnsObjects(const aHandle: TltsPostProcessorHandle; var aValue: Boolean): TltsErrorCode; stdcall; +var + pp: TtsPostProcessorList; +begin + try + result := ltsErrNone; + if CheckPostProcessorHandle(aHandle, TtsPostProcessorList, pp) + then aValue := pp.OwnsObjects + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsPostProcessorListSetOwnsObjects(const aHandle: TltsPostProcessorHandle; const aValue: Boolean): TltsErrorCode; stdcall; +var + pp: TtsPostProcessorList; +begin + try + result := ltsErrNone; + if CheckPostProcessorHandle(aHandle, TtsPostProcessorList, pp) + then pp.OwnsObjects := aValue + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsPostProcessorListAdd(const aHandle, aItem: TltsPostProcessorHandle): TltsErrorCode; stdcall; +var + pp, itm: TtsPostProcessorList; +begin + try + result := ltsErrNone; + if CheckPostProcessorHandle(aHandle, TtsPostProcessorList, pp) and + CheckPostProcessorHandle(aItem, TtsPostProcessor, itm) + then pp.Add(itm) + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsPostProcessorListDel(const aHandle: TltsPostProcessorHandle; const aIndex: Integer): TltsErrorCode; stdcall; +var + pp: TtsPostProcessorList; +begin + try + result := ltsErrNone; + if CheckPostProcessorHandle(aHandle, TtsPostProcessorList, pp) then begin + if (aIndex < 0) or (aIndex >= pp.Count) then begin + SetLastError(ltsErrInvalidValue, 'index is out of range'); + result := LastErrorCode + end + else pp.Delete(aIndex); + end else + result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsPostProcessorListClear(const aHandle: TltsPostProcessorHandle): TltsErrorCode; stdcall; +var + pp: TtsPostProcessorList; +begin + try + result := ltsErrNone; + if CheckPostProcessorHandle(aHandle, TtsPostProcessorList, pp) + then pp.ClearRanges + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsPostProcessorListRem(const aHandle, aItem: TltsPostProcessorHandle): Integer; stdcall; +var + pp, itm: TtsPostProcessorList; +begin + try + result := -1; + if CheckPostProcessorHandle(aHandle, TtsPostProcessorList, pp) and + CheckPostProcessorHandle(aItem, TtsPostProcessor, itm) + then result := pp.Remove(itm) + else result := -1; + except + on ex: Exception do begin + SetLastError(ex); + result := -1; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsPostProcessorListIndexOf(const aHandle, aItem: TltsPostProcessorHandle): Integer; stdcall; +var + pp, itm: TtsPostProcessorList; +begin + try + result := -1; + if CheckPostProcessorHandle(aHandle, TtsPostProcessorList, pp) and + CheckPostProcessorHandle(aItem, TtsPostProcessor, itm) + then result := pp.IndexOf(itm) + else result := -1; + except + on ex: Exception do begin + SetLastError(ex); + result := -1; + end; + end; +end; + +end. + diff --git a/ultsRenderer.pas b/ultsRenderer.pas new file mode 100644 index 0000000..103c891 --- /dev/null +++ b/ultsRenderer.pas @@ -0,0 +1,212 @@ +unit ultsRenderer; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, + ultsTypes, + utsTextSuite, utsUtils; + +function ltsRendererCreate (const aHandle: TltsContextHandle; const aType: TltsRendererType; const aFormat: TtsFormat): 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; +function ltsRendererGetTextWidthA(const aHandle: TltsRendererHandle; const aFont: TltsFontHandle; const aText: PAnsiChar): Integer; stdcall; +function ltsRendererGetTextWidthW(const aHandle: TltsRendererHandle; const aFont: TltsFontHandle; const aText: PWideChar): Integer; stdcall; +function ltsRendererDestroy (const aHandle: TltsRendererHandle): TltsErrorCode; stdcall; + +implementation + +uses + ultsUtils; + +type +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TltsRendererOpenGL = class(TtsRendererOpenGL) + public + procedure DelSlave(const aSlave: TtsRefManager); override; + end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + TltsRendererOpenGLES = class(TtsRendererOpenGLES) + public + procedure DelSlave(const aSlave: TtsRefManager); override; + end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//TltsRendererOpenGL//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TltsRendererOpenGL.DelSlave(const aSlave: TtsRefManager); +begin + DelReference(aSlave); + inherited DelSlave(aSlave); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//TltsRendererOpenGLES////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure TltsRendererOpenGLES.DelSlave(const aSlave: TtsRefManager); +begin + DelReference(aSlave); + inherited DelSlave(aSlave); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//Renderer////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsRendererCreate(const aHandle: TltsContextHandle; const aType: TltsRendererType; const aFormat: TtsFormat): TltsRendererHandle; stdcall; +var + c: TtsContext; + r: TtsRenderer; +begin + try + result := nil; + if not CheckContextHandle(aHandle, c) then + exit; + + if not ValidateFormat(aFormat) then begin + SetLastError(ltsErrInvalidEnum, Format('%d is not a valid format', [aFormat])); + exit; + end; + + case aType of + ltsRendererOpenGL: r := TltsRendererOpenGL.Create(c, aFormat); + ltsRendererOpenGLES: r := TltsRendererOpenGLES.Create(c, aFormat); + // TODO ltsRendererCustom: r := TltsRendererCustom.Create(c, aFormat); + else + SetLastError(ltsErrInvalidEnum, Format('%d is not a valid renderer type', [aType])); + exit; + end; + 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 + r: TtsRenderer; + b: TtsTextBlock; +begin + try + result := nil; + if CheckRendererHandle(aHandle, r) then begin + b := r.BeginBlock(aTop, aLeft, aWidth, aHeight, aFlags); + AddReference(ltsObjTypeTextBlock, b); + result := b; + end; + except + on ex: Exception do begin + SetLastError(ex); + result := nil; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsRendererEndBlock(const aHandle: TltsRendererHandle; const aBlock: TltsTextBlockHandle): TltsErrorCode; stdcall; +var + r: TtsRenderer; + b: TtsTextBlock; +begin + try + result := ltsErrNone; + if CheckRendererHandle(aHandle, r) and CheckTextBlockHandle(aBlock, b) then begin + DelReference(ltsObjTypeTextBlock, b); + r.EndBlock(b); + end else + result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsRendererAbortBlock(const aHandle: TltsRendererHandle; const aBlock: TltsTextBlockHandle): TltsErrorCode; stdcall; +var + r: TtsRenderer; + b: TtsTextBlock; +begin + try + result := ltsErrNone; + if CheckRendererHandle(aHandle, r) and CheckTextBlockHandle(aBlock, b) then begin + DelReference(ltsObjTypeTextBlock, b); + r.AbortBlock(b); + end else + result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsRendererGetTextWidthA(const aHandle: TltsRendererHandle; const aFont: TltsFontHandle; const aText: PAnsiChar): Integer; stdcall; +var + r: TtsRenderer; + f: TtsFont; +begin + try + if CheckRendererHandle(aHandle, r) and CheckFontHandle(aFont, f) + then result := r.GetTextWidthA(f, aText) + else result := -1; + except + on ex: Exception do begin + SetLastError(ex); + result := -1; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsRendererGetTextWidthW(const aHandle: TltsRendererHandle; const aFont: TltsFontHandle; const aText: PWideChar): Integer; stdcall; +var + r: TtsRenderer; + f: TtsFont; +begin + try + if CheckRendererHandle(aHandle, r) and CheckFontHandle(aFont, f) + then result := r.GetTextWidthW(f, aText) + else result := -1; + except + on ex: Exception do begin + SetLastError(ex); + result := -1; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsRendererDestroy(const aHandle: TltsRendererHandle): TltsErrorCode; stdcall; +var + r: TtsRenderer; +begin + try + result := ltsErrNone; + if CheckRendererHandle(aHandle, r) then begin + DelReference(ltsObjTypeRenderer, r); + FreeAndNil(r); + end else + result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +end. + diff --git a/ultsTextBlock.pas b/ultsTextBlock.pas new file mode 100644 index 0000000..91054b3 --- /dev/null +++ b/ultsTextBlock.pas @@ -0,0 +1,460 @@ +unit ultsTextBlock; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, + utsTextSuite, + ultsTypes; + +function ltsTextBlockGetRect (const aHandle: TltsTextBlockHandle; var aValue: TtsRect): TltsErrorCode; stdcall; +function ltsTextBlockGetWidth (const aHandle: TltsTextBlockHandle; var aValue: Integer): TltsErrorCode; stdcall; +function ltsTextBlockGetHeight (const aHandle: TltsTextBlockHandle; var aValue: Integer): TltsErrorCode; stdcall; +function ltsTextBlockGetFlags (const aHandle: TltsTextBlockHandle; var aValue: TtsBlockFlags): TltsErrorCode; stdcall; + +function ltsTextBlockGetTop (const aHandle: TltsTextBlockHandle; var aValue: Integer): TltsErrorCode; stdcall; +function ltsTextBlockGetLeft (const aHandle: TltsTextBlockHandle; var aValue: Integer): TltsErrorCode; stdcall; +function ltsTextBlockGetVertAlign (const aHandle: TltsTextBlockHandle; var aValue: TtsVertAlignment): TltsErrorCode; stdcall; +function ltsTextBlockGetHorzAlign (const aHandle: TltsTextBlockHandle; var aValue: TtsHorzAlignment): TltsErrorCode; stdcall; +function ltsTextBlockGetClipping (const aHandle: TltsTextBlockHandle; var aValue: TtsClipping): TltsErrorCode; stdcall; +function ltsTextBlockGetColor (const aHandle: TltsTextBlockHandle; var aValue: TtsColor4f): TltsErrorCode; stdcall; +function ltsTextBlockGetFont (const aHandle: TltsTextBlockHandle; var aValue: TltsFontHandle): TltsErrorCode; stdcall; + +function ltsTextBlockSetTop (const aHandle: TltsTextBlockHandle; const aValue: Integer): TltsErrorCode; stdcall; +function ltsTextBlockSetLeft (const aHandle: TltsTextBlockHandle; const aValue: Integer): TltsErrorCode; stdcall; +function ltsTextBlockSetVertAlign (const aHandle: TltsTextBlockHandle; const aValue: TtsVertAlignment): TltsErrorCode; stdcall; +function ltsTextBlockSetHorzAlign (const aHandle: TltsTextBlockHandle; const aValue: TtsHorzAlignment): TltsErrorCode; stdcall; +function ltsTextBlockSetClipping (const aHandle: TltsTextBlockHandle; const aValue: TtsClipping): TltsErrorCode; stdcall; +function ltsTextBlockSetColor (const aHandle: TltsTextBlockHandle; const aValue: TtsColor4f): TltsErrorCode; stdcall; +function ltsTextBlockSetFont (const aHandle: TltsTextBlockHandle; const aValue: TltsFontHandle): TltsErrorCode; stdcall; + +function ltsTextBlockGetActualHeight(const aHandle: TltsTextBlockHandle): Integer; stdcall; +function ltsTextBlockGetTextWidthA (const aHandle: TltsTextBlockHandle; const aText: PAnsiChar): Integer; stdcall; +function ltsTextBlockGetTextWidthW (const aHandle: TltsTextBlockHandle; const aText: PWideChar): Integer; stdcall; + +function ltsTextBlockTextOutA (const aHandle: TltsTextBlockHandle; const aText: PAnsiChar): TltsErrorCode; stdcall; +function ltsTextBlockTextOutW (const aHandle: TltsTextBlockHandle; const aText: PWideChar): TltsErrorCode; stdcall; + +implementation + +uses + ultsUtils; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//TextBlock///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsTextBlockGetRect(const aHandle: TltsTextBlockHandle; var aValue: TtsRect): TltsErrorCode; stdcall; +var + b: TtsTextBlock; +begin + try + result := ltsErrNone; + if CheckTextBlockHandle(aHandle, b) + then aValue := b.Rect + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsTextBlockGetWidth(const aHandle: TltsTextBlockHandle; var aValue: Integer): TltsErrorCode; stdcall; +var + b: TtsTextBlock; +begin + try + result := ltsErrNone; + if CheckTextBlockHandle(aHandle, b) + then aValue := b.Width + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsTextBlockGetHeight(const aHandle: TltsTextBlockHandle; var aValue: Integer): TltsErrorCode; stdcall; +var + b: TtsTextBlock; +begin + try + result := ltsErrNone; + if CheckTextBlockHandle(aHandle, b) + then aValue := b.Height + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsTextBlockGetFlags(const aHandle: TltsTextBlockHandle; var aValue: TtsBlockFlags): TltsErrorCode; stdcall; +var + b: TtsTextBlock; +begin + try + result := ltsErrNone; + if CheckTextBlockHandle(aHandle, b) + then aValue := b.Flags + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsTextBlockGetTop(const aHandle: TltsTextBlockHandle; var aValue: Integer): TltsErrorCode; stdcall; +var + b: TtsTextBlock; +begin + try + result := ltsErrNone; + if CheckTextBlockHandle(aHandle, b) + then aValue := b.Top + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsTextBlockGetLeft(const aHandle: TltsTextBlockHandle; var aValue: Integer): TltsErrorCode; stdcall; +var + b: TtsTextBlock; +begin + try + result := ltsErrNone; + if CheckTextBlockHandle(aHandle, b) + then aValue := b.Left + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsTextBlockGetVertAlign(const aHandle: TltsTextBlockHandle; var aValue: TtsVertAlignment): TltsErrorCode; stdcall; +var + b: TtsTextBlock; +begin + try + result := ltsErrNone; + if CheckTextBlockHandle(aHandle, b) + then aValue := b.VertAlign + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsTextBlockGetHorzAlign(const aHandle: TltsTextBlockHandle; var aValue: TtsHorzAlignment): TltsErrorCode; stdcall; +var + b: TtsTextBlock; +begin + try + result := ltsErrNone; + if CheckTextBlockHandle(aHandle, b) + then aValue := b.HorzAlign + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsTextBlockGetClipping(const aHandle: TltsTextBlockHandle; var aValue: TtsClipping): TltsErrorCode; stdcall; +var + b: TtsTextBlock; +begin + try + result := ltsErrNone; + if CheckTextBlockHandle(aHandle, b) + then aValue := b.Clipping + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsTextBlockGetColor(const aHandle: TltsTextBlockHandle; var aValue: TtsColor4f): TltsErrorCode; stdcall; +var + b: TtsTextBlock; +begin + try + result := ltsErrNone; + if CheckTextBlockHandle(aHandle, b) + then aValue := b.CurrentColor + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsTextBlockGetFont(const aHandle: TltsTextBlockHandle; var aValue: TltsFontHandle): TltsErrorCode; stdcall; +var + b: TtsTextBlock; +begin + try + result := ltsErrNone; + if CheckTextBlockHandle(aHandle, b) + then aValue := b.CurrentFont + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsTextBlockSetTop(const aHandle: TltsTextBlockHandle; const aValue: Integer): TltsErrorCode; stdcall; +var + b: TtsTextBlock; +begin + try + result := ltsErrNone; + if CheckTextBlockHandle(aHandle, b) + then b.Top := aValue + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsTextBlockSetLeft(const aHandle: TltsTextBlockHandle; const aValue: Integer): TltsErrorCode; stdcall; +var + b: TtsTextBlock; +begin + try + result := ltsErrNone; + if CheckTextBlockHandle(aHandle, b) + then b.Left := aValue + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsTextBlockSetVertAlign(const aHandle: TltsTextBlockHandle; const aValue: TtsVertAlignment): TltsErrorCode; stdcall; +var + b: TtsTextBlock; +begin + try + result := ltsErrNone; + if CheckTextBlockHandle(aHandle, b) + then b.VertAlign := aValue + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsTextBlockSetHorzAlign(const aHandle: TltsTextBlockHandle; const aValue: TtsHorzAlignment): TltsErrorCode; stdcall; +var + b: TtsTextBlock; +begin + try + result := ltsErrNone; + if CheckTextBlockHandle(aHandle, b) + then b.HorzAlign := aValue + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsTextBlockSetClipping(const aHandle: TltsTextBlockHandle; const aValue: TtsClipping): TltsErrorCode; stdcall; +var + b: TtsTextBlock; +begin + try + result := ltsErrNone; + if CheckTextBlockHandle(aHandle, b) + then b.Clipping := aValue + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsTextBlockSetColor(const aHandle: TltsTextBlockHandle; const aValue: TtsColor4f): TltsErrorCode; stdcall; +var + b: TtsTextBlock; +begin + try + result := ltsErrNone; + if CheckTextBlockHandle(aHandle, b) + then b.CurrentColor := aValue + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsTextBlockSetFont(const aHandle: TltsTextBlockHandle; const aValue: TltsFontHandle): TltsErrorCode; stdcall; +var + b: TtsTextBlock; + f: TtsFont; +begin + try + result := ltsErrNone; + if CheckTextBlockHandle(aHandle, b) and CheckFontHandle(aValue, f) + then b.CurrentFont := f + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsTextBlockGetActualHeight(const aHandle: TltsTextBlockHandle): Integer; stdcall; +var + b: TtsTextBlock; +begin + try + if CheckTextBlockHandle(aHandle, b) + then result := b.GetActualBlockHeight + else result := -1; + except + on ex: Exception do begin + SetLastError(ex); + result := -1; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsTextBlockGetTextWidthA(const aHandle: TltsTextBlockHandle; const aText: PAnsiChar): Integer; stdcall; +var + b: TtsTextBlock; +begin + try + if CheckTextBlockHandle(aHandle, b) + then result := b.GetTextWidthA(aText) + else result := -1; + except + on ex: Exception do begin + SetLastError(ex); + result := -1; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsTextBlockGetTextWidthW(const aHandle: TltsTextBlockHandle; const aText: PWideChar): Integer; stdcall; +var + b: TtsTextBlock; +begin + try + if CheckTextBlockHandle(aHandle, b) + then result := b.GetTextWidthW(aText) + else result := -1; + except + on ex: Exception do begin + SetLastError(ex); + result := -1; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsTextBlockTextOutA(const aHandle: TltsTextBlockHandle; const aText: PAnsiChar): TltsErrorCode; stdcall; +var + b: TtsTextBlock; +begin + try + result := ltsErrNone; + if CheckTextBlockHandle(aHandle, b) + then b.TextOutA(aText) + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ltsTextBlockTextOutW(const aHandle: TltsTextBlockHandle; const aText: PWideChar): TltsErrorCode; stdcall; +var + b: TtsTextBlock; +begin + try + result := ltsErrNone; + if CheckTextBlockHandle(aHandle, b) + then b.TextOutW(aText) + else result := LastErrorCode; + except + on ex: Exception do begin + SetLastError(ex); + result := LastErrorCode; + end; + end; +end; + +end. + diff --git a/ultsTypes.pas b/ultsTypes.pas new file mode 100644 index 0000000..ae54810 --- /dev/null +++ b/ultsTypes.pas @@ -0,0 +1,88 @@ +unit ultsTypes; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils; + +type + {$Z4} + TltsErrorCode = ( + ltsErrUnknown = -1, + ltsErrNone = 0, + + // misc + ltsErrNotInitialized = 1, + ltsErrInvalidEnum = 2, + ltsErrInvalidValue = 3, + ltsErrInvalidOperation = 4, + ltsErrInvalidType = 5, + + // invalid handles + ltsErrInvalidContextHandle = 100, + ltsErrInvalidRendererHandle = 101, + ltsErrInvalidTextBlockHandle = 102, + ltsErrInvalidFontHandle = 103, + ltsErrInvalidFontCreatorHandle = 104, + ltsErrInvalidImageHandle = 105, + ltsErrInvalidPostProcHandle = 106 + ); + + {$Z4} + TltsObjectType = ( + ltsObjTypeUnknown, + ltsObjTypeContext, + ltsObjTypeRenderer, + ltsObjTypeFontCreator, + ltsObjTypeFont, + ltsObjTypeTextBlock, + ltsObjTypeImage, + ltsObjTypePostProcessor + ); + + {$Z4} + TltsRendererType = ( + ltsRendererUnknown, + ltsRendererOpenGL, + ltsRendererOpenGLES, + ltsRendererCustom + ); + + {$Z4} + TltsFontCreatorType = ( + ltsFontCreatorUnknown, + ltsFontCreatorFreeType, + ltsFontCreatorGDI, + ltsFontCreatorCustom + ); + + TltsHandle = Pointer; + TltsContextHandle = TltsHandle; + TltsRendererHandle = TltsHandle; + TltsTextBlockHandle = TltsHandle; + TltsFontCreatorHandle = TltsHandle; + TltsFontHandle = TltsHandle; + TltsPostProcessorHandle = TltsHandle; + TltsImageHandle = TltsHandle; + + TltsStreamOrigin = ( + ltsStreamOriginBegin = Integer(soBeginning), + ltsStreamOriginCurrent = Integer(soCurrent), + ltsStreamOriginEnd = Integer(soEnd) + ); + + TltsStreamFuncRead = function(const aArgs: Pointer; const aBuffer: Pointer; const aSize: Integer): Integer; stdcall; + TltsStreamFuncSeek = function(const aArgs: Pointer; const aOrigin: TltsStreamOrigin; const aPos: Integer): Integer; stdcall; + PltsStream = ^TltsStream; + TltsStream = packed record + args: Pointer; + read: TltsStreamFuncRead; + seek: TltsStreamFuncSeek; + end; + +implementation + +end. + diff --git a/ultsUtils.pas b/ultsUtils.pas new file mode 100644 index 0000000..e52796f --- /dev/null +++ b/ultsUtils.pas @@ -0,0 +1,312 @@ +unit ultsUtils; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, + uutlGenerics, + ultsTypes, + utsTextSuite; + +type + TtsPostProcessorClass = class of TtsPostProcessor; + +procedure SetLastError(const aEx: Exception); +procedure SetLastError(const aErrorCode: TltsErrorCode; const aErrorMsg: String); + +function CheckIfInitialized: Boolean; +function CheckContextHandle(const aHandle: TltsContextHandle; out aContext: TtsContext): Boolean; +function CheckRendererHandle(const aHandle: TltsContextHandle; out aRenderer: TtsRenderer): Boolean; +function CheckTextBlockHandle(const aHandle: TltsTextBlockHandle; out aTextBlock: TtsTextBlock): Boolean; +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 CheckPostProcessorHandle(const aHandle: TltsPostProcessorHandle; const aType: TtsPostProcessorClass; out aPostProcessor): Boolean; + +procedure AddReference(const aType: TltsObjectType; const aRef: TObject); +procedure DelReference(const aType: TltsObjectType; const aRef: TObject); +procedure DelReference(const aRef: TObject); + +function ValidateCodePage(const aValue: TtsCodePage): Boolean; +function ValidateFormat(const aValue: TtsFormat): Boolean; +function ValidateCharRangeUsage(const aValue: TtsCharRangeUsage): Boolean; + +procedure Initialize; +procedure Finalize; + +type + TltsStreamImpl = class(TStream) + private + fStream: PltsStream; + public + function Read(var Buffer; Count: Longint): Longint; override; + function Seek(Offset: Longint; Origin: Word): Longint; override; overload; + + constructor Create(const aStream: PltsStream); + end; + +var + LastErrorCode: TltsErrorCode = ltsErrNone; + LastErrorMsg: String; + +implementation + +type + TtsContextHashSet = specialize TutlHashSet; + TtsRendererHashSet = specialize TutlHashSet; + TtsTextBlockHashSet = specialize TutlHashSet; + TtsFontHashSet = specialize TutlHashSet; + TtsFontCreatorHashSet = specialize TutlHashSet; + TtsImageHashSet = specialize TutlHashSet; + TtsPostProcessorHashSet = specialize TutlHashSet; + +var + IsInitilized: Boolean = false; + + Contexts: TtsContextHashSet = nil; + Renderers: TtsRendererHashSet = nil; + TextBlocks: TtsTextBlockHashSet = nil; + Fonts: TtsFontHashSet = nil; + FontCreators: TtsFontCreatorHashSet = nil; + Images: TtsImageHashSet = nil; + PostProcessors: TtsPostProcessorHashSet = nil; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure SetLastError(const aEx: Exception); +begin + LastErrorCode := ltsErrUnknown; + LastErrorMsg := aEx.Message; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure SetLastError(const aErrorCode: TltsErrorCode; const aErrorMsg: String); +begin + LastErrorCode := aErrorCode; + LastErrorMsg := aErrorMsg; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function CheckIfInitialized: Boolean; +begin + result := IsInitilized; + if not result then + SetLastError(ltsErrNotInitialized, 'libTextSuite has not been initialized. call ltsInitialize before using any other methods.'); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function CheckContextHandle(const aHandle: TltsContextHandle; out aContext: TtsContext): Boolean; +begin + result := CheckIfInitialized; + if result then begin + aContext := TtsContext(aHandle); + result := Contexts.Contains(aContext); + if not result then + SetLastError(ltsErrInvalidContextHandle, Format('0x%.16x is not a valid context handle', [{%H-}PtrUInt(aHandle)])); + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function CheckRendererHandle(const aHandle: TltsContextHandle; out aRenderer: TtsRenderer): Boolean; +begin + result := CheckIfInitialized; + if result then begin + aRenderer := TtsRenderer(aHandle); + result := Renderers.Contains(aRenderer); + if not result then + SetLastError(ltsErrInvalidRendererHandle, Format('0x%.16x is not a valid renderer handle', [{%H-}PtrUInt(aHandle)])); + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function CheckTextBlockHandle(const aHandle: TltsTextBlockHandle; out aTextBlock: TtsTextBlock): Boolean; +begin + result := CheckIfInitialized; + if result then begin + aTextBlock := TtsTextBlock(aHandle); + result := TextBlocks.Contains(aTextBlock); + if not result then + SetLastError(ltsErrInvalidTextBlockHandle, Format('0x%.16x is no a valid text block handle', [{%H-}PtrUInt(aHandle)])); + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function CheckFontHandle(const aHandle: TltsFontHandle; out aFont: TtsFont): Boolean; +begin + result := CheckIfInitialized; + if result then begin + aFont := TtsFont(aHandle); + result := Fonts.Contains(aFont); + if not result then + SetLastError(ltsErrInvalidFontHandle, Format('0x%.16x is no a valid font handle', [{%H-}PtrUInt(aHandle)])); + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function CheckFontCreatorHandle(const aHandle: TltsFontCreatorHandle; out aFontCreator: TtsFontCreator): Boolean; +begin + result := CheckIfInitialized; + if result then begin + aFontCreator := TtsFontCreator(aHandle); + result := FontCreators.Contains(aFontCreator); + if not result then + SetLastError(ltsErrInvalidFontCreatorHandle, Format('0x%.16x is no a valid font creator handle', [{%H-}PtrUInt(aHandle)])); + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function CheckImageHandle(const aHandle: TltsImageHandle; out aImage: TtsImage): Boolean; +begin + result := CheckIfInitialized; + if result then begin + aImage := TtsImage(aHandle); + result := Images.Contains(aImage); + if not result then + SetLastError(ltsErrInvalidImageHandle, Format('0x%.16x is no a valid image handle', [{%H-}PtrUInt(aHandle)])); + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function CheckPostProcessorHandle(const aHandle: TltsPostProcessorHandle; const aType: TtsPostProcessorClass; out aPostProcessor): Boolean; +begin + result := CheckIfInitialized; + if result then begin + TtsPostProcessor(aPostProcessor) := TtsPostProcessor(aHandle); + result := PostProcessors.Contains(TtsPostProcessor(aPostProcessor)); + if not result then begin + SetLastError(ltsErrInvalidPostProcHandle, Format('0x%.16x is no a valid image handle', [{%H-}PtrUInt(aHandle)])); + exit; + end; + result := (TtsPostProcessor(aPostProcessor) is aType); + if not result then begin + SetLastError(ltsErrInvalidType, Format('0x%.16x is no a %s post processor', [{%H-}PtrUInt(aHandle), aType.ClassName])); + exit; + end; + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure AddReference(const aType: TltsObjectType; const aRef: TObject); +begin + case aType of + ltsObjTypeContext: Contexts.Add(aRef as TtsContext); + ltsObjTypeRenderer: Renderers.Add(aRef as TtsRenderer); + ltsObjTypeFont: Fonts.Add(aRef as TtsFont); + ltsObjTypeTextBlock: TextBlocks.Add(aRef as TtsTextBlock); + ltsObjTypeFontCreator: FontCreators.Add(aRef as TtsFontCreator); + ltsObjTypeImage: Images.Add(aRef as TtsImage); + ltsObjTypePostProcessor: PostProcessors.Add(aRef as TtsPostProcessor); + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure DelReference(const aType: TltsObjectType; const aRef: TObject); +begin + case aType of + ltsObjTypeContext: Contexts.Remove(aRef as TtsContext); + ltsObjTypeRenderer: Renderers.Remove(aRef as TtsRenderer); + ltsObjTypeFont: Fonts.Remove(aRef as TtsFont); + ltsObjTypeTextBlock: TextBlocks.Remove(aRef as TtsTextBlock); + ltsObjTypeFontCreator: FontCreators.Remove(aRef as TtsFontCreator); + ltsObjTypeImage: Images.Remove(aRef as TtsImage); + ltsObjTypePostProcessor: PostProcessors.Remove(aRef as TtsPostProcessor); + end; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure DelReference(const aRef: TObject); +begin + if (aRef is TtsRenderer) then + DelReference(ltsObjTypeRenderer, aRef) + else if (aRef is TtsTextBlock) then + DelReference(ltsObjTypeTextBlock, aRef) + else if (aRef is TtsFont) then + DelReference(ltsObjTypeFont, aRef) + else if (aRef is TtsContext) then + DelReference(ltsObjTypeContext, aRef) + else if (aRef is TtsFontCreator) then + DelReference(ltsObjTypeFontCreator, aRef) + else if (aRef is TtsImage) then + DelReference(ltsObjTypeImage, aRef) + else if (aRef is TtsPostProcessor) then + DelReference(ltsObjTypePostProcessor, aRef); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ValidateCodePage(const aValue: TtsCodePage): Boolean; +begin + result := (aValue >= Low(TtsCodePage)) and (aValue <= High(TtsCodePage)); + if not result then + SetLastError(ltsErrInvalidEnum, Format('%d is not a valid code page value', [aValue])); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ValidateFormat(const aValue: TtsFormat): Boolean; +begin + result := (aValue >= Low(TtsFormat)) and (aValue <= High(TtsFormat)); + if not result then + SetLastError(ltsErrInvalidEnum, Format('%d is not a valid format value', [aValue])); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function ValidateCharRangeUsage(const aValue: TtsCharRangeUsage): Boolean; +begin + result := (aValue >= Low(TtsCharRangeUsage)) and (aValue <= High(TtsCharRangeUsage)); + if not result then + SetLastError(ltsErrInvalidEnum, Format('%d is not a valid char range usage value', [aValue])); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure Initialize; +begin + Contexts := TtsContextHashSet.Create(true); + Renderers := TtsRendererHashSet.Create(false); + TextBlocks := TtsTextBlockHashSet.Create(false); + FontCreators := TtsFontCreatorHashSet.Create(false); + Fonts := TtsFontHashSet.Create(false); + Images := TtsImageHashSet.Create(false); + PostProcessors := TtsPostProcessorHashSet.Create(false); + IsInitilized := true; +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +procedure Finalize; +begin + IsInitilized := false; + FreeAndNil(PostProcessors); + FreeAndNil(Images); + FreeAndNil(TextBlocks); + FreeAndNil(Fonts); + FreeAndNil(FontCreators); + FreeAndNil(Renderers); + FreeAndNil(Contexts); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//TltsStreamImpl//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function TltsStreamImpl.Read(var Buffer; Count: Longint): Longint; +begin + if not Assigned(fStream) or not Assigned(fStream^.read) + then result := inherited Read(Buffer, Count) + else result := fStream^.read(fStream^.args, @buffer, Count); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +function TltsStreamImpl.Seek(Offset: Longint; Origin: Word): Longint; +begin + if not Assigned(fStream) or not Assigned(fStream^.seek) + then result := inherited Seek(Offset, Origin) + else result := fStream^.seek(fStream^.args, TltsStreamOrigin(Origin), Offset); +end; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +constructor TltsStreamImpl.Create(const aStream: PltsStream); +begin + inherited Create; + fStream := aStream; +end; + +end. + diff --git a/utsTextSuite.inc b/utsTextSuite.inc new file mode 100644 index 0000000..695359f --- /dev/null +++ b/utsTextSuite.inc @@ -0,0 +1,4 @@ +{$DEFINE TS_ENABLE_OPENGL_SUPPORT} +{$DEFINE TS_ENABLE_OPENGLES_SUPPORT} +{$DEFINE TS_ENABLE_GDI_SUPPORT} +{$DEFINE TS_ENABLE_FREETYPE_SUPPORT}