Просмотр исходного кода

* improved glyph metric calculation

* removed old files / projects
* added three simple examples
master
Bergmann89 11 лет назад
Родитель
Сommit
e4ee2cf65d
42 измененных файлов: 922 добавлений и 13770 удалений
  1. +0
    -3
      .gitmodules
  2. +0
    -1
      OpenGLCore
  3. Двоичные данные
     
  4. +83
    -0
      examples/PostProcess/PostProcess.lpi
  5. +21
    -0
      examples/PostProcess/PostProcess.lpr
  6. +12
    -0
      examples/PostProcess/uMainForm.lfm
  7. +145
    -0
      examples/PostProcess/uMainForm.pas
  8. Двоичные данные
     
  9. +83
    -0
      examples/SimpleFreeType/SimpleFreeType.lpi
  10. +21
    -0
      examples/SimpleFreeType/SimpleFreeType.lpr
  11. Двоичные данные
     
  12. Двоичные данные
     
  13. +12
    -0
      examples/SimpleFreeType/uMainForm.lfm
  14. +101
    -0
      examples/SimpleFreeType/uMainForm.pas
  15. +83
    -0
      examples/SimpleGDI/SimpleGDI.lpi
  16. +21
    -0
      examples/SimpleGDI/SimpleGDI.lpr
  17. +12
    -0
      examples/SimpleGDI/uMainForm.lfm
  18. +101
    -0
      examples/SimpleGDI/uMainForm.pas
  19. Двоичные данные
     
  20. +0
    -137
      examples/simple/TextSuiteTest.lpi
  21. +0
    -27
      examples/simple/TextSuiteTest.lpr
  22. +0
    -646
      examples/simple/TextSuiteTest.lps
  23. Двоичные данные
     
  24. +0
    -15
      examples/simple/uMainForm.lfm
  25. +0
    -179
      examples/simple/uMainForm.pas
  26. +0
    -3649
      old/TextSuite.pas
  27. +0
    -142
      old/TextSuiteCPUUtils.pas
  28. +0
    -5761
      old/TextSuiteClasses.pas
  29. +0
    -866
      old/TextSuiteImports.pas
  30. +0
    -46
      old/TextSuiteOptions.inc
  31. +0
    -397
      old/TextSuitePostProcess.pas
  32. +0
    -366
      old/TextSuiteTTFUtils.pas
  33. +0
    -13
      old/TextSuiteVersion.pas
  34. +0
    -1393
      old/TextSuiteWideUtils.pas
  35. +79
    -41
      utsFontCreatorFreeType.pas
  36. +3
    -3
      utsFontCreatorGDI.pas
  37. +27
    -14
      utsFreeType.pas
  38. +11
    -7
      utsOpenGLUtils.pas
  39. +26
    -17
      utsPostProcess.pas
  40. +9
    -3
      utsRendererOpenGL.pas
  41. +11
    -4
      utsRendererOpenGLES.pas
  42. +61
    -40
      utsTextSuite.pas

+ 0
- 3
.gitmodules Просмотреть файл

@@ -1,3 +0,0 @@
[submodule "OpenGLCore"]
path = OpenGLCore
url = ../lazopenglcore.git

+ 0
- 1
OpenGLCore

@@ -1 +0,0 @@
Subproject commit f6ca47eeb2c217505d9c1babe79d46b6668d3881

Двоичные данные
Просмотреть файл


+ 83
- 0
examples/PostProcess/PostProcess.lpi Просмотреть файл

@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="9"/>
<PathDelim Value="\"/>
<General>
<SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/>
<Title Value="PostProcess"/>
<ResourceType Value="res"/>
<UseXPManifest Value="True"/>
<Icon Value="0"/>
</General>
<i18n>
<EnableI18N LFM="False"/>
</i18n>
<VersionInfo>
<StringTable ProductVersion=""/>
</VersionInfo>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
</PublishOptions>
<RunParams>
<local>
<FormatVersion Value="1"/>
</local>
</RunParams>
<RequiredPackages Count="1">
<Item1>
<PackageName Value="LCL"/>
</Item1>
</RequiredPackages>
<Units Count="2">
<Unit0>
<Filename Value="PostProcess.lpr"/>
<IsPartOfProject Value="True"/>
</Unit0>
<Unit1>
<Filename Value="uMainForm.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="MainForm"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="uMainForm"/>
</Unit1>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="PostProcess"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<OtherUnitFiles Value="..\lib;..\.."/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Linking>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
</CompilerOptions>
<Debugging>
<Exceptions Count="3">
<Item1>
<Name Value="EAbort"/>
</Item1>
<Item2>
<Name Value="ECodetoolError"/>
</Item2>
<Item3>
<Name Value="EFOpenError"/>
</Item3>
</Exceptions>
</Debugging>
</CONFIG>

+ 21
- 0
examples/PostProcess/PostProcess.lpr Просмотреть файл

@@ -0,0 +1,21 @@
program PostProcess;

{$mode objfpc}{$H+}

uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Interfaces, // this includes the LCL widgetset
Forms, uMainForm
{ you can add units after this };

{$R *.res}

begin
RequireDerivedFormResource := True;
Application.Initialize;
Application.CreateForm(TMainForm, MainForm);
Application.Run;
end.


+ 12
- 0
examples/PostProcess/uMainForm.lfm Просмотреть файл

@@ -0,0 +1,12 @@
object MainForm: TMainForm
Left = 473
Height = 600
Top = 244
Width = 800
Caption = 'MainForm'
OnCreate = FormCreate
OnDestroy = FormDestroy
OnPaint = FormPaint
Position = poScreenCenter
LCLVersion = '1.3'
end

+ 145
- 0
examples/PostProcess/uMainForm.pas Просмотреть файл

@@ -0,0 +1,145 @@
unit uMainForm;

{$mode objfpc}{$H+}

interface

uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
uglcContext,
utsTextSuite, utsRendererOpenGL, utsFontCreatorGDI, utsTypes, utsPostProcess;

type
TMainForm = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormPaint(Sender: TObject);
private
fContext: TglcContext;
ftsContext: TtsContext;
ftsRenderer: TtsRendererOpenGL;
ftsCreator1: TtsFontGeneratorGDI;
ftsCreator2: TtsFontGeneratorGDI;
ftsFont1: TtsFont;
ftsFont2: TtsFont;
procedure Render;
public
{ public declarations }
end;

var
MainForm: TMainForm;

implementation

{$R *.lfm}

uses
dglOpenGL;

const
TEST_TEXT = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum.';

procedure TMainForm.FormCreate(Sender: TObject);
var
pf: TglcContextPixelFormatSettings;
pp: TtsPostProcessStep;
img: TtsImage;

const
PATTER_DATA: array[0..15] of Byte = (
$FF, $BF, $7F, $BF,
$BF, $FF, $BF, $7F,
$7F, $BF, $FF, $BF,
$BF, $7F, $BF, $FF);

begin
pf := TglcContext.MakePF();
fContext := TglcContext.GetPlatformClass.Create(self, pf);
fContext.BuildContext;

ftsContext := TtsContext.Create;
ftsRenderer := TtsRendererOpenGL.Create(ftsContext, tsFormatRGBA8);

ftsCreator1 := TtsFontGeneratorGDI.Create(ftsContext);
ftsFont1 := ftsCreator1.GetFontByFile(ExtractFilePath(Application.ExeName) + '../Prototype.ttf', ftsRenderer, 40, [], tsAANormal);

pp := TtsPostProcessFillColor.Create(tsColor4f(0, 0, 0, 1), TS_MODES_REPLACE_ALL, TS_CHANNELS_RGB);
pp.AddUsageChars(tsUsageExclude, 'Lorem');
ftsCreator1.AddPostProcessStep(pp);

pp := TtsPostProcessFillColor.Create(tsColor4f(1.0, 0.0, 0.0, 1.0), TS_MODES_MODULATE_ALL, TS_CHANNELS_RGB);
pp.AddUsageChars(tsUsageInclude, 'Lorem');
ftsCreator1.AddPostProcessStep(pp);

img := TtsImage.Create;
img.CreateEmpty(tsFormatAlpha8, 4, 4);
Move(PATTER_DATA[0], img.Data^, 16);
pp := TtsPostProcessFillPattern.Create(img, true, 0, 0, TS_MODES_MODULATE_ALL, TS_CHANNELS_RGBA);
pp.AddUsageChars(tsUsageInclude, 'Lorem');
ftsCreator1.AddPostProcessStep(pp);

ftsCreator2 := TtsFontGeneratorGDI.Create(ftsContext);
ftsFont2 := ftsCreator2.GetFontByFile(ExtractFilePath(Application.ExeName) + '../Prototype.ttf', ftsRenderer, 40, [tsStyleStrikeout], tsAANormal);

pp := TtsPostProcessFillColor.Create(tsColor4f(0, 0, 0.5, 1), TS_MODES_REPLACE_ALL, TS_CHANNELS_RGB);
pp.AddUsageChars(tsUsageExclude, 'e');
ftsCreator2.AddPostProcessStep(pp);

pp := TtsPostProcessBorder.Create(3.0, 0.5, tsColor4f(0.0, 0.5, 0.0, 1.0), true);
pp.AddUsageChars(tsUsageInclude, 'e');
ftsCreator2.AddPostProcessStep(pp);
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
FreeAndNil(ftsFont2);
FreeAndNil(ftsCreator2);
FreeAndNil(ftsFont1);
FreeAndNil(ftsCreator1);
FreeAndNil(ftsRenderer);
FreeAndNil(ftsContext);
FreeAndNil(fContext);
end;

procedure TMainForm.FormPaint(Sender: TObject);
begin
if Assigned(fContext) then begin
Render;
fContext.SwapBuffers;
end;
end;

procedure TMainForm.Render;
var
block: TtsTextBlock;
begin
glClearColor(1, 1, 1, 1);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

glViewport(0, 0, ClientWidth, ClientHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glOrtho(0, ClientWidth, ClientHeight, 0, -10, 10);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

block := ftsRenderer.BeginBlock(10, 10, ClientWidth-20, ClientHeight-20, [tsBlockFlagWordWrap]);
try
block.HorzAlign := tsHorzAlignJustify;
block.ChangeFont(ftsFont1);
block.ChangeColor(tsColor4f(1.0, 1.0, 1.0, 1.0));
block.TextOutW(TEST_TEXT + sLineBreak);

block.ChangeFont(ftsFont2);
block.TextOutW(TEST_TEXT);
finally
ftsRenderer.EndBlock(block);
end;
end;

end.


Двоичные данные
Просмотреть файл


+ 83
- 0
examples/SimpleFreeType/SimpleFreeType.lpi Просмотреть файл

@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="9"/>
<PathDelim Value="\"/>
<General>
<SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/>
<Title Value="SimpleFreeType"/>
<ResourceType Value="res"/>
<UseXPManifest Value="True"/>
<Icon Value="0"/>
</General>
<i18n>
<EnableI18N LFM="False"/>
</i18n>
<VersionInfo>
<StringTable ProductVersion=""/>
</VersionInfo>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
</PublishOptions>
<RunParams>
<local>
<FormatVersion Value="1"/>
</local>
</RunParams>
<RequiredPackages Count="1">
<Item1>
<PackageName Value="LCL"/>
</Item1>
</RequiredPackages>
<Units Count="2">
<Unit0>
<Filename Value="SimpleFreeType.lpr"/>
<IsPartOfProject Value="True"/>
</Unit0>
<Unit1>
<Filename Value="uMainForm.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="MainForm"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="uMainForm"/>
</Unit1>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="SimpleFreeType"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<OtherUnitFiles Value="..\lib;..\.."/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Linking>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
</CompilerOptions>
<Debugging>
<Exceptions Count="3">
<Item1>
<Name Value="EAbort"/>
</Item1>
<Item2>
<Name Value="ECodetoolError"/>
</Item2>
<Item3>
<Name Value="EFOpenError"/>
</Item3>
</Exceptions>
</Debugging>
</CONFIG>

+ 21
- 0
examples/SimpleFreeType/SimpleFreeType.lpr Просмотреть файл

@@ -0,0 +1,21 @@
program SimpleFreeType;

{$mode objfpc}{$H+}

uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Interfaces, // this includes the LCL widgetset
Forms, uMainForm
{ you can add units after this };

{$R *.res}

begin
RequireDerivedFormResource := True;
Application.Initialize;
Application.CreateForm(TMainForm, MainForm);
Application.Run;
end.


Двоичные данные
Просмотреть файл


Двоичные данные
Просмотреть файл


+ 12
- 0
examples/SimpleFreeType/uMainForm.lfm Просмотреть файл

@@ -0,0 +1,12 @@
object MainForm: TMainForm
Left = 670
Height = 320
Top = 319
Width = 480
Caption = 'MainForm'
OnCreate = FormCreate
OnDestroy = FormDestroy
OnPaint = FormPaint
Position = poScreenCenter
LCLVersion = '1.3'
end

+ 101
- 0
examples/SimpleFreeType/uMainForm.pas Просмотреть файл

@@ -0,0 +1,101 @@
unit uMainForm;

{$mode objfpc}{$H+}

interface

uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
uglcContext,
utsTextSuite, utsRendererOpenGL, utsFontCreatorFreeType, utsTypes;

type
TMainForm = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormPaint(Sender: TObject);
private
fContext: TglcContext;
ftsContext: TtsContext;
ftsRenderer: TtsRendererOpenGL;
ftsCreator: TtsFontGeneratorFreeType;
ftsFont: TtsFont;
procedure Render;
public
{ public declarations }
end;

var
MainForm: TMainForm;

implementation

{$R *.lfm}

uses
dglOpenGL;

const
TEST_TEXT = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.';

procedure TMainForm.FormCreate(Sender: TObject);
var
pf: TglcContextPixelFormatSettings;
begin
pf := TglcContext.MakePF();
fContext := TglcContext.GetPlatformClass.Create(self, pf);
fContext.BuildContext;

ftsContext := TtsContext.Create;
ftsRenderer := TtsRendererOpenGL.Create(ftsContext, tsFormatAlpha8);
ftsCreator := TtsFontGeneratorFreeType.Create(ftsContext);
ftsFont := ftsCreator.GetFontByFile(ExtractFilePath(Application.ExeName) + '../Prototype.ttf', ftsRenderer, 20, [], tsAANormal);
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
FreeAndNil(ftsFont);
FreeAndNil(ftsCreator);
FreeAndNil(ftsRenderer);
FreeAndNil(ftsContext);
FreeAndNil(fContext);
end;

procedure TMainForm.FormPaint(Sender: TObject);
begin
if Assigned(fContext) then begin
Render;
fContext.SwapBuffers;
end;
end;

procedure TMainForm.Render;
var
block: TtsTextBlock;
begin
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

glViewport(0, 0, ClientWidth, ClientHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glOrtho(0, ClientWidth, ClientHeight, 0, -10, 10);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

block := ftsRenderer.BeginBlock(10, 10, ClientWidth-20, ClientHeight-20, [tsBlockFlagWordWrap]);
try
block.HorzAlign := tsHorzAlignJustify;
block.ChangeFont(ftsFont);
block.ChangeColor(tsColor4f(1.0, 1.0, 1.0, 1.0));
block.TextOutW(TEST_TEXT);
finally
ftsRenderer.EndBlock(block);
end;
end;

end.


+ 83
- 0
examples/SimpleGDI/SimpleGDI.lpi Просмотреть файл

@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="9"/>
<PathDelim Value="\"/>
<General>
<SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/>
<Title Value="SimpleGDI"/>
<ResourceType Value="res"/>
<UseXPManifest Value="True"/>
<Icon Value="0"/>
</General>
<i18n>
<EnableI18N LFM="False"/>
</i18n>
<VersionInfo>
<StringTable ProductVersion=""/>
</VersionInfo>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
</PublishOptions>
<RunParams>
<local>
<FormatVersion Value="1"/>
</local>
</RunParams>
<RequiredPackages Count="1">
<Item1>
<PackageName Value="LCL"/>
</Item1>
</RequiredPackages>
<Units Count="2">
<Unit0>
<Filename Value="SimpleGDI.lpr"/>
<IsPartOfProject Value="True"/>
</Unit0>
<Unit1>
<Filename Value="uMainForm.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="MainForm"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<UnitName Value="uMainForm"/>
</Unit1>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="SimpleGDI"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<OtherUnitFiles Value="..\lib;..\.."/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Linking>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
</CompilerOptions>
<Debugging>
<Exceptions Count="3">
<Item1>
<Name Value="EAbort"/>
</Item1>
<Item2>
<Name Value="ECodetoolError"/>
</Item2>
<Item3>
<Name Value="EFOpenError"/>
</Item3>
</Exceptions>
</Debugging>
</CONFIG>

+ 21
- 0
examples/SimpleGDI/SimpleGDI.lpr Просмотреть файл

@@ -0,0 +1,21 @@
program SimpleGDI;

{$mode objfpc}{$H+}

uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Interfaces, // this includes the LCL widgetset
Forms, uMainForm
{ you can add units after this };

{$R *.res}

begin
RequireDerivedFormResource := True;
Application.Initialize;
Application.CreateForm(TMainForm, MainForm);
Application.Run;
end.


+ 12
- 0
examples/SimpleGDI/uMainForm.lfm Просмотреть файл

@@ -0,0 +1,12 @@
object MainForm: TMainForm
Left = 670
Height = 320
Top = 319
Width = 480
Caption = 'MainForm'
OnCreate = FormCreate
OnDestroy = FormDestroy
OnPaint = FormPaint
Position = poScreenCenter
LCLVersion = '1.3'
end

+ 101
- 0
examples/SimpleGDI/uMainForm.pas Просмотреть файл

@@ -0,0 +1,101 @@
unit uMainForm;

{$mode objfpc}{$H+}

interface

uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
uglcContext,
utsTextSuite, utsRendererOpenGL, utsFontCreatorGDI, utsTypes;

type
TMainForm = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormPaint(Sender: TObject);
private
fContext: TglcContext;
ftsContext: TtsContext;
ftsRenderer: TtsRendererOpenGL;
ftsCreator: TtsFontGeneratorGDI;
ftsFont: TtsFont;
procedure Render;
public
{ public declarations }
end;

var
MainForm: TMainForm;

implementation

{$R *.lfm}

uses
dglOpenGL;

const
TEST_TEXT = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.';

procedure TMainForm.FormCreate(Sender: TObject);
var
pf: TglcContextPixelFormatSettings;
begin
pf := TglcContext.MakePF();
fContext := TglcContext.GetPlatformClass.Create(self, pf);
fContext.BuildContext;

ftsContext := TtsContext.Create;
ftsRenderer := TtsRendererOpenGL.Create(ftsContext, tsFormatAlpha8);
ftsCreator := TtsFontGeneratorGDI.Create(ftsContext);
ftsFont := ftsCreator.GetFontByFile(ExtractFilePath(Application.ExeName) + '../Prototype.ttf', ftsRenderer, 20, [], tsAANormal);
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
FreeAndNil(ftsFont);
FreeAndNil(ftsCreator);
FreeAndNil(ftsRenderer);
FreeAndNil(ftsContext);
FreeAndNil(fContext);
end;

procedure TMainForm.FormPaint(Sender: TObject);
begin
if Assigned(fContext) then begin
Render;
fContext.SwapBuffers;
end;
end;

procedure TMainForm.Render;
var
block: TtsTextBlock;
begin
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

glViewport(0, 0, ClientWidth, ClientHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glOrtho(0, ClientWidth, ClientHeight, 0, -10, 10);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

block := ftsRenderer.BeginBlock(10, 10, ClientWidth-20, ClientHeight-20, [tsBlockFlagWordWrap]);
try
block.HorzAlign := tsHorzAlignJustify;
block.ChangeFont(ftsFont);
block.ChangeColor(tsColor4f(1.0, 1.0, 1.0, 1.0));
block.TextOutW(TEST_TEXT);
finally
ftsRenderer.EndBlock(block);
end;
end;

end.


Двоичные данные
Просмотреть файл


+ 0
- 137
examples/simple/TextSuiteTest.lpi Просмотреть файл

@@ -1,137 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectOptions>
<Version Value="9"/>
<PathDelim Value="\"/>
<General>
<SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/>
<Title Value="TextSuiteTest"/>
<ResourceType Value="res"/>
<UseXPManifest Value="True"/>
<Icon Value="0"/>
</General>
<i18n>
<EnableI18N LFM="False"/>
</i18n>
<VersionInfo>
<StringTable ProductVersion=""/>
</VersionInfo>
<BuildModes Count="1">
<Item1 Name="Default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
</PublishOptions>
<RunParams>
<local>
<FormatVersion Value="1"/>
</local>
</RunParams>
<RequiredPackages Count="1">
<Item1>
<PackageName Value="LCL"/>
</Item1>
</RequiredPackages>
<Units Count="14">
<Unit0>
<Filename Value="TextSuiteTest.lpr"/>
<IsPartOfProject Value="True"/>
</Unit0>
<Unit1>
<Filename Value="uMainForm.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="MainForm"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
</Unit1>
<Unit2>
<Filename Value="..\..\utsRendererOpenGL.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="utsRendererOpenGL"/>
</Unit2>
<Unit3>
<Filename Value="..\..\utsTextSuite.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="utsTextSuite"/>
</Unit3>
<Unit4>
<Filename Value="..\..\utsTtfUtils.pas"/>
<IsPartOfProject Value="True"/>
</Unit4>
<Unit5>
<Filename Value="..\..\utsTypes.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="utsTypes"/>
</Unit5>
<Unit6>
<Filename Value="..\..\utsUtils.pas"/>
<IsPartOfProject Value="True"/>
</Unit6>
<Unit7>
<Filename Value="..\..\utsFontCreatorGDI.pas"/>
<IsPartOfProject Value="True"/>
</Unit7>
<Unit8>
<Filename Value="..\..\utsCodePages.pas"/>
<IsPartOfProject Value="True"/>
</Unit8>
<Unit9>
<Filename Value="..\..\utsPostProcess.pas"/>
<IsPartOfProject Value="True"/>
</Unit9>
<Unit10>
<Filename Value="..\..\utsFontCreatorFreeType.pas"/>
<IsPartOfProject Value="True"/>
</Unit10>
<Unit11>
<Filename Value="..\..\utsGDI.pas"/>
<IsPartOfProject Value="True"/>
</Unit11>
<Unit12>
<Filename Value="..\..\utsFreeType.pas"/>
<IsPartOfProject Value="True"/>
</Unit12>
<Unit13>
<Filename Value="..\..\utsOpenGLUtils.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="utsOpenGLUtils"/>
</Unit13>
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="11"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="TextSuiteTest"/>
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir);old"/>
<OtherUnitFiles Value="..\..;..\..\old;..\..\OpenGLCore;..\..\..\dglOpenGLES"/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Linking>
<Debugging>
<UseHeaptrc Value="True"/>
</Debugging>
<Options>
<Win32>
<GraphicApplication Value="True"/>
</Win32>
</Options>
</Linking>
</CompilerOptions>
<Debugging>
<Exceptions Count="3">
<Item1>
<Name Value="EAbort"/>
</Item1>
<Item2>
<Name Value="ECodetoolError"/>
</Item2>
<Item3>
<Name Value="EFOpenError"/>
</Item3>
</Exceptions>
</Debugging>
</CONFIG>

+ 0
- 27
examples/simple/TextSuiteTest.lpr Просмотреть файл

@@ -1,27 +0,0 @@
program TextSuiteTest;

{$mode objfpc}{$H+}

uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Interfaces, sysutils, Forms, uMainForm, utsFontCreatorGDI, utsUtils, utsTypes, utsTtfUtils, utsTextSuite,
utsRendererOpenGL, utsCodePages, utsPostProcess, utsFontCreatorFreeType, utsGDI, utsFreeType, utsOpenGLUtils;

{$R *.res}

var
HeapTraceLogFile: String;
begin
HeapTraceLogFile := ExtractFilePath(Application.ExeName) + 'heaptrace.log';
if FileExists(HeapTraceLogFile) then
DeleteFile(HeapTraceLogFile);
SetHeapTraceOutput(HeapTraceLogFile);

RequireDerivedFormResource := True;
Application.Initialize;
Application.CreateForm(TMainForm, MainForm);
Application.Run;
end.


+ 0
- 646
examples/simple/TextSuiteTest.lps Просмотреть файл

@@ -1,646 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<CONFIG>
<ProjectSession>
<PathDelim Value="\"/>
<Version Value="9"/>
<BuildModes Active="Default"/>
<Units Count="67">
<Unit0>
<Filename Value="TextSuiteTest.lpr"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<CursorPos X="29" Y="20"/>
<UsageCount Value="142"/>
</Unit0>
<Unit1>
<Filename Value="uMainForm.pas"/>
<IsPartOfProject Value="True"/>
<ComponentName Value="MainForm"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<EditorIndex Value="-1"/>
<TopLine Value="140"/>
<CursorPos X="59" Y="154"/>
<UsageCount Value="142"/>
</Unit1>
<Unit2>
<Filename Value="..\..\utsRendererOpenGL.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="utsRendererOpenGL"/>
<IsVisibleTab Value="True"/>
<WindowIndex Value="1"/>
<TopLine Value="171"/>
<CursorPos Y="187"/>
<UsageCount Value="70"/>
<Loaded Value="True"/>
</Unit2>
<Unit3>
<Filename Value="..\..\utsTextSuite.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="utsTextSuite"/>
<TopLine Value="216"/>
<CursorPos X="55" Y="316"/>
<UsageCount Value="70"/>
<Loaded Value="True"/>
</Unit3>
<Unit4>
<Filename Value="..\..\utsTtfUtils.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<UsageCount Value="70"/>
</Unit4>
<Unit5>
<Filename Value="..\..\utsTypes.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="utsTypes"/>
<EditorIndex Value="4"/>
<TopLine Value="173"/>
<CursorPos X="59" Y="191"/>
<UsageCount Value="70"/>
<Loaded Value="True"/>
</Unit5>
<Unit6>
<Filename Value="..\..\utsUtils.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="174"/>
<CursorPos X="26" Y="194"/>
<UsageCount Value="70"/>
</Unit6>
<Unit7>
<Filename Value="..\..\utsFontCreatorGDI.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="-1"/>
<TopLine Value="517"/>
<CursorPos Y="526"/>
<UsageCount Value="70"/>
</Unit7>
<Unit8>
<Filename Value="..\..\utsCodePages.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="315"/>
<CursorPos X="21" Y="325"/>
<UsageCount Value="67"/>
</Unit8>
<Unit9>
<Filename Value="..\..\utsPostProcess.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="216"/>
<CursorPos X="30" Y="227"/>
<UsageCount Value="65"/>
</Unit9>
<Unit10>
<Filename Value="..\..\utsFontCreatorFreeType.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<TopLine Value="237"/>
<CursorPos X="51" Y="339"/>
<UsageCount Value="54"/>
</Unit10>
<Unit11>
<Filename Value="..\..\utsGDI.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<TopLine Value="284"/>
<CursorPos X="12" Y="298"/>
<UsageCount Value="46"/>
</Unit11>
<Unit12>
<Filename Value="..\..\utsFreeType.pas"/>
<IsPartOfProject Value="True"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<TopLine Value="292"/>
<CursorPos X="31" Y="308"/>
<UsageCount Value="46"/>
</Unit12>
<Unit13>
<Filename Value="..\..\utsOpenGLUtils.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="utsOpenGLUtils"/>
<IsVisibleTab Value="True"/>
<EditorIndex Value="3"/>
<TopLine Value="206"/>
<CursorPos X="40" Y="220"/>
<UsageCount Value="21"/>
<Loaded Value="True"/>
</Unit13>
<Unit14>
<Filename Value="..\..\utsRendererOpenGLES.pas"/>
<UnitName Value="utsRendererOpenGLES"/>
<EditorIndex Value="1"/>
<TopLine Value="172"/>
<CursorPos Y="12"/>
<UsageCount Value="20"/>
<Loaded Value="True"/>
</Unit14>
<Unit15>
<Filename Value="new\utsTextSuite.pas"/>
<EditorIndex Value="-1"/>
<TopLine Value="1886"/>
<CursorPos X="33" Y="1904"/>
<UsageCount Value="89"/>
</Unit15>
<Unit16>
<Filename Value="old\TextSuite.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<TopLine Value="391"/>
<CursorPos X="13" Y="408"/>
<ExtraEditorCount Value="1"/>
<ExtraEditor1>
<EditorIndex Value="-1"/>
<TopLine Value="232"/>
<CursorPos X="3" Y="302"/>
</ExtraEditor1>
<UsageCount Value="84"/>
</Unit16>
<Unit17>
<Filename Value="old\TextSuiteImports.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<TopLine Value="656"/>
<CursorPos X="20" Y="635"/>
<UsageCount Value="84"/>
</Unit17>
<Unit18>
<Filename Value="old\TextSuiteWideUtils.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<TopLine Value="1243"/>
<CursorPos X="18" Y="1257"/>
<UsageCount Value="84"/>
</Unit18>
<Unit19>
<Filename Value="old\TextSuiteClasses.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<TopLine Value="654"/>
<CursorPos X="25" Y="673"/>
<UsageCount Value="84"/>
</Unit19>
<Unit20>
<Filename Value="old\TextSuitePostProcess.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<TopLine Value="163"/>
<CursorPos X="61" Y="141"/>
<UsageCount Value="84"/>
</Unit20>
<Unit21>
<Filename Value="old\TextSuiteTTFUtils.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<TopLine Value="83"/>
<CursorPos X="3" Y="91"/>
<UsageCount Value="84"/>
</Unit21>
<Unit22>
<Filename Value="old\TextSuiteVersion.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="-1"/>
<TopLine Value="-1"/>
<CursorPos X="-1" Y="-1"/>
<UsageCount Value="84"/>
</Unit22>
<Unit23>
<Filename Value="new\utsFontCreatorGDI.pas"/>
<EditorIndex Value="-1"/>
<TopLine Value="655"/>
<CursorPos X="53" Y="662"/>
<UsageCount Value="48"/>
</Unit23>
<Unit24>
<Filename Value="new\utsTtfUtils.pas"/>
<EditorIndex Value="-1"/>
<TopLine Value="128"/>
<CursorPos X="17" Y="144"/>
<UsageCount Value="40"/>
</Unit24>
<Unit25>
<Filename Value="new\utsTypes.pas"/>
<EditorIndex Value="-1"/>
<TopLine Value="152"/>
<CursorPos X="5" Y="168"/>
<UsageCount Value="40"/>
</Unit25>
<Unit26>
<Filename Value="new\utsUtils.pas"/>
<EditorIndex Value="-1"/>
<CursorPos Y="20"/>
<UsageCount Value="40"/>
</Unit26>
<Unit27>
<Filename Value="new\utsRendererOpenGL.pas"/>
<EditorIndex Value="-1"/>
<TopLine Value="356"/>
<CursorPos X="20" Y="376"/>
<UsageCount Value="37"/>
</Unit27>
<Unit28>
<Filename Value="..\bitSpace\_projects\MassiveUniverseOnline\bitSpaceEngine\src\OpenGLCore\uglcTypes.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<TopLine Value="261"/>
<CursorPos X="3" Y="277"/>
<UsageCount Value="35"/>
</Unit28>
<Unit29>
<Filename Value="..\bitSpace\_projects\MassiveUniverseOnline\bitSpaceEngine\src\OpenGLCore\dglOpenGL.pas"/>
<EditorIndex Value="-1"/>
<TopLine Value="1066"/>
<CursorPos X="27" Y="1082"/>
<UsageCount Value="30"/>
</Unit29>
<Unit30>
<Filename Value="new\uglctextsuite.pas"/>
<EditorIndex Value="-1"/>
<CursorPos X="3" Y="13"/>
<UsageCount Value="11"/>
</Unit30>
<Unit31>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\rtl\inc\ustringh.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="113"/>
<CursorPos X="10" Y="129"/>
<UsageCount Value="38"/>
</Unit31>
<Unit32>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\rtl\inc\ustrings.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="2091"/>
<CursorPos X="5" Y="2098"/>
<UsageCount Value="21"/>
</Unit32>
<Unit33>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\rtl\inc\systemh.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="502"/>
<CursorPos X="3" Y="518"/>
<UsageCount Value="36"/>
</Unit33>
<Unit34>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\rtl\inc\heaph.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="71"/>
<CursorPos X="10" Y="95"/>
<UsageCount Value="24"/>
</Unit34>
<Unit35>
<Filename Value="old\TextSuiteCPUUtils.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<CursorPos X="23" Y="20"/>
<UsageCount Value="14"/>
</Unit35>
<Unit36>
<Filename Value="..\glBitmap\glBitmap\glBitmap.pas"/>
<EditorIndex Value="-1"/>
<CursorPos X="14" Y="14"/>
<UsageCount Value="2"/>
</Unit36>
<Unit37>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\rtl\objpas\math.pp"/>
<EditorIndex Value="-1"/>
<TopLine Value="1011"/>
<CursorPos X="47" Y="1015"/>
<UsageCount Value="6"/>
</Unit37>
<Unit38>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\rtl\inc\mathh.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="84"/>
<CursorPos X="14" Y="101"/>
<UsageCount Value="6"/>
</Unit38>
<Unit39>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\rtl\inc\genmath.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="152"/>
<CursorPos X="10" Y="155"/>
<UsageCount Value="6"/>
</Unit39>
<Unit40>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\rtl\inc\dynlibs.pas"/>
<EditorIndex Value="-1"/>
<TopLine Value="143"/>
<CursorPos X="3" Y="149"/>
<UsageCount Value="30"/>
</Unit40>
<Unit41>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\rtl\win\dynlibs.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="26"/>
<CursorPos X="10" Y="42"/>
<UsageCount Value="28"/>
</Unit41>
<Unit42>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\rtl\win\sysosh.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="11"/>
<CursorPos X="3" Y="19"/>
<UsageCount Value="11"/>
</Unit42>
<Unit43>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\rtl\inc\objpash.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="177"/>
<CursorPos X="22" Y="195"/>
<UsageCount Value="15"/>
</Unit43>
<Unit44>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\rtl\objpas\sysutils\sysunih.inc"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<TopLine Value="25"/>
<CursorPos X="34" Y="43"/>
<UsageCount Value="26"/>
</Unit44>
<Unit45>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\packages\fcl-base\src\syncobjs.pp"/>
<EditorIndex Value="-1"/>
<TopLine Value="113"/>
<CursorPos X="25" Y="115"/>
<UsageCount Value="16"/>
</Unit45>
<Unit46>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\rtl\objpas\classes\classesh.inc"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<TopLine Value="311"/>
<CursorPos X="14" Y="327"/>
<UsageCount Value="23"/>
</Unit46>
<Unit47>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\rtl\inc\objpas.inc"/>
<EditorIndex Value="-1"/>
<UsageCount Value="29"/>
</Unit47>
<Unit48>
<Filename Value="C:\Zusatzprogramme\Lazarus\lcl\include\control.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="2843"/>
<CursorPos Y="2858"/>
<UsageCount Value="13"/>
</Unit48>
<Unit49>
<Filename Value="C:\Users\Erik\Desktop\RectPacking\unit1.pas"/>
<ComponentName Value="Form1"/>
<HasResources Value="True"/>
<ResourceBaseClass Value="Form"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<TopLine Value="376"/>
<CursorPos X="74" Y="397"/>
<UsageCount Value="21"/>
</Unit49>
<Unit50>
<Filename Value="..\bitSpace\_projects\MassiveUniverseOnline\bitSpaceEngine\src\OpenGLCore\uglcArrayBuffer.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<TopLine Value="102"/>
<CursorPos X="37" Y="112"/>
<UsageCount Value="10"/>
</Unit50>
<Unit51>
<Filename Value="..\bitSpace\_projects\MassiveUniverseOnline\bitSpaceEngine\src\OpenGLCore\uglcBitmap.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<TopLine Value="1047"/>
<CursorPos X="15" Y="1043"/>
<UsageCount Value="8"/>
</Unit51>
<Unit52>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\rtl\objpas\objpas.pp"/>
<EditorIndex Value="-1"/>
<TopLine Value="19"/>
<CursorPos X="8" Y="35"/>
<UsageCount Value="8"/>
</Unit52>
<Unit53>
<Filename Value="C:\Zusatzprogramme\Lazarus\lcl\include\application.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="966"/>
<CursorPos Y="981"/>
<UsageCount Value="8"/>
</Unit53>
<Unit54>
<Filename Value="..\bitSpace\_projects\MassiveUniverseOnline\bitSpaceEngine\src\SpaceEngine\uengFrameLimiter.pas"/>
<EditorIndex Value="-1"/>
<TopLine Value="14"/>
<CursorPos X="13" Y="14"/>
<UsageCount Value="8"/>
</Unit54>
<Unit55>
<Filename Value="..\..\old\TextSuiteClasses.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<TopLine Value="2705"/>
<CursorPos X="3" Y="2698"/>
<UsageCount Value="18"/>
</Unit55>
<Unit56>
<Filename Value="..\..\old\TextSuite.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<TopLine Value="29"/>
<CursorPos X="3" Y="45"/>
<UsageCount Value="14"/>
</Unit56>
<Unit57>
<Filename Value="..\..\old\TextSuiteWideUtils.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<TopLine Value="1362"/>
<CursorPos X="3" Y="1390"/>
<UsageCount Value="14"/>
</Unit57>
<Unit58>
<Filename Value="..\..\utsWideStringUtils.pas"/>
<EditorIndex Value="-1"/>
<CursorPos Y="9"/>
<UsageCount Value="18"/>
</Unit58>
<Unit59>
<Filename Value="..\..\old\TextSuiteCPUUtils.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<UsageCount Value="13"/>
</Unit59>
<Unit60>
<Filename Value="..\..\old\TextSuiteImports.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<CursorPos X="41" Y="12"/>
<UsageCount Value="13"/>
</Unit60>
<Unit61>
<Filename Value="..\..\old\TextSuiteOptions.inc"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<UsageCount Value="13"/>
</Unit61>
<Unit62>
<Filename Value="..\..\old\TextSuitePostProcess.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<TopLine Value="261"/>
<CursorPos X="23" Y="345"/>
<UsageCount Value="13"/>
</Unit62>
<Unit63>
<Filename Value="..\..\old\TextSuiteTTFUtils.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<UsageCount Value="13"/>
</Unit63>
<Unit64>
<Filename Value="..\..\old\TextSuiteVersion.pas"/>
<EditorIndex Value="-1"/>
<WindowIndex Value="1"/>
<UsageCount Value="13"/>
</Unit64>
<Unit65>
<Filename Value="C:\Zusatzprogramme\Lazarus\fpc\2.7.1\source\rtl\win\wininc\unifun.inc"/>
<EditorIndex Value="-1"/>
<TopLine Value="53"/>
<CursorPos X="22" Y="69"/>
<UsageCount Value="26"/>
</Unit65>
<Unit66>
<Filename Value="..\..\..\dglOpenGLES\dglOpenGLES.pas"/>
<UnitName Value="dglOpenGLES"/>
<EditorIndex Value="2"/>
<TopLine Value="64"/>
<CursorPos X="48" Y="74"/>
<UsageCount Value="10"/>
<Loaded Value="True"/>
</Unit66>
</Units>
<JumpHistory Count="30" HistoryIndex="29">
<Position1>
<Filename Value="..\..\utsRendererOpenGLES.pas"/>
<Caret Line="17" Column="22" TopLine="5"/>
</Position1>
<Position2>
<Filename Value="..\..\..\dglOpenGLES\dglOpenGLES.pas"/>
</Position2>
<Position3>
<Filename Value="..\..\utsRendererOpenGL.pas"/>
<Caret Line="210" Column="38" TopLine="196"/>
</Position3>
<Position4>
<Filename Value="..\..\utsOpenGLUtils.pas"/>
<Caret Line="378" Column="31" TopLine="297"/>
</Position4>
<Position5>
<Filename Value="..\..\utsOpenGLUtils.pas"/>
<Caret Line="21" Column="26" TopLine="5"/>
</Position5>
<Position6>
<Filename Value="..\..\utsOpenGLUtils.pas"/>
<Caret Line="54" TopLine="39"/>
</Position6>
<Position7>
<Filename Value="..\..\utsOpenGLUtils.pas"/>
<Caret Line="53" TopLine="41"/>
</Position7>
<Position8>
<Filename Value="..\..\utsOpenGLUtils.pas"/>
<Caret Line="143" Column="120" TopLine="133"/>
</Position8>
<Position9>
<Filename Value="..\..\utsOpenGLUtils.pas"/>
<Caret Line="74" Column="15" TopLine="63"/>
</Position9>
<Position10>
<Filename Value="..\..\utsOpenGLUtils.pas"/>
<Caret Line="191" Column="5" TopLine="177"/>
</Position10>
<Position11>
<Filename Value="..\..\utsOpenGLUtils.pas"/>
<Caret Line="132" Column="3" TopLine="128"/>
</Position11>
<Position12>
<Filename Value="..\..\utsOpenGLUtils.pas"/>
<Caret Line="190" Column="24" TopLine="176"/>
</Position12>
<Position13>
<Filename Value="..\..\utsTypes.pas"/>
<Caret Line="186" Column="55" TopLine="170"/>
</Position13>
<Position14>
<Filename Value="..\..\utsOpenGLUtils.pas"/>
<Caret Line="190" Column="24" TopLine="176"/>
</Position14>
<Position15>
<Filename Value="..\..\utsOpenGLUtils.pas"/>
<Caret Line="192" Column="7" TopLine="174"/>
</Position15>
<Position16>
<Filename Value="..\..\utsOpenGLUtils.pas"/>
<Caret Line="194" Column="45" TopLine="178"/>
</Position16>
<Position17>
<Filename Value="..\..\utsOpenGLUtils.pas"/>
<Caret Line="53" TopLine="9"/>
</Position17>
<Position18>
<Filename Value="..\..\utsOpenGLUtils.pas"/>
<Caret Line="198" Column="12" TopLine="187"/>
</Position18>
<Position19>
<Filename Value="..\..\utsOpenGLUtils.pas"/>
<Caret Line="207" Column="7" TopLine="187"/>
</Position19>
<Position20>
<Filename Value="..\..\utsOpenGLUtils.pas"/>
<Caret Line="205" Column="22" TopLine="189"/>
</Position20>
<Position21>
<Filename Value="..\..\utsOpenGLUtils.pas"/>
<Caret Line="216" TopLine="192"/>
</Position21>
<Position22>
<Filename Value="..\..\utsOpenGLUtils.pas"/>
<Caret Line="207" Column="71" TopLine="193"/>
</Position22>
<Position23>
<Filename Value="..\..\utsOpenGLUtils.pas"/>
<Caret Line="274" Column="17" TopLine="259"/>
</Position23>
<Position24>
<Filename Value="..\..\utsOpenGLUtils.pas"/>
<Caret Line="18" Column="5" TopLine="2"/>
</Position24>
<Position25>
<Filename Value="..\..\utsRendererOpenGL.pas"/>
<Caret Line="75" Column="5" TopLine="73"/>
</Position25>
<Position26>
<Filename Value="..\..\utsOpenGLUtils.pas"/>
<Caret Line="62" Column="67" TopLine="47"/>
</Position26>
<Position27>
<Filename Value="..\..\utsRendererOpenGL.pas"/>
<Caret Line="19" Column="15" TopLine="3"/>
</Position27>
<Position28>
<Filename Value="..\..\..\dglOpenGLES\dglOpenGLES.pas"/>
<Caret Line="59" Column="33" TopLine="52"/>
</Position28>
<Position29>
<Filename Value="..\..\utsRendererOpenGL.pas"/>
<Caret Line="191" Column="39" TopLine="171"/>
</Position29>
<Position30>
<Filename Value="..\..\utsOpenGLUtils.pas"/>
<Caret Line="225" Column="19" TopLine="206"/>
</Position30>
</JumpHistory>
</ProjectSession>
</CONFIG>

Двоичные данные
Просмотреть файл


+ 0
- 15
examples/simple/uMainForm.lfm Просмотреть файл

@@ -1,15 +0,0 @@
object MainForm: TMainForm
Left = 536
Height = 508
Top = 255
Width = 682
OnCreate = FormCreate
OnDestroy = FormDestroy
OnPaint = FormPaint
LCLVersion = '1.3'
object ApplicationProperties: TApplicationProperties
OnIdle = ApplicationPropertiesIdle
left = 56
top = 24
end
end

+ 0
- 179
examples/simple/uMainForm.pas Просмотреть файл

@@ -1,179 +0,0 @@
unit uMainForm;

{$mode objfpc}{$H+}

{.$DEFINE USE_OLD_TS}

interface

uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, uglcContext, uglcTypes,
utsTextSuite, utsTypes, utsFontCreatorGDI, utsRendererOpenGL, utsPostProcess, utsFontCreatorFreeType;

type
TMainForm = class(TForm)
ApplicationProperties: TApplicationProperties;
procedure ApplicationPropertiesIdle(Sender: TObject; var Done: Boolean);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormPaint(Sender: TObject);
private
fFrameTime: QWord;
fFrameCount: Integer;
fSecTime: QWord;
fContext: TglcContext;
{$IFDEF USE_OLD_TS}
ftsContext: tsContextID;
ftsFont: tsFontID;
{$ELSE}
ftsContext: TtsContext;
ftsRenderer: TtsRendererOpenGL;
ftsGenerator: TtsFontGeneratorGDI;
ftsFreeType: TtsFontGeneratorFreeType;
ftsFont1: TtsFont;
ftsFont2: TtsFont;
ftsFont3: TtsFont;
{$ENDIF}
procedure Render;
public
{ public declarations }
end;

var
MainForm: TMainForm;

implementation

{$R *.lfm}

uses
dglOpenGL;

const
TEST_STRING = 'Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.';

procedure TMainForm.FormCreate(Sender: TObject);
var
pf: TglcContextPixelFormatSettings;
pp: TtsPostProcessStep;
begin
pf := TglcContext.MakePF();
fContext := TglcContext.GetPlatformClass.Create(self, pf);
fContext.BuildContext;
{$IFDEF USE_OLD_TS}
tsInit(TS_INIT_TEXTSUITE or TS_INIT_OPENGL or TS_INIT_GDI);
tsContextCreate(@ftsContext);
tsSetParameteri(TS_RENDERER, TS_RENDERER_OPENGL);
tsSetParameteri(TS_CREATOR, TS_CREATOR_GDI_FACENAME);
tsContextBind(ftsContext);
tsFontCreateCreatorA('Calibri', 25, 0, TS_ANTIALIASING_NORMAL, TS_DEFAULT, @ftsFont);
tsFontBind(ftsFont);
{$ELSE}
ftsContext := TtsContext.Create;
ftsRenderer := TtsRendererOpenGL.Create(ftsContext, tsFormatRGBA8);
ftsGenerator := TtsFontGeneratorGDI.Create(ftsContext);

ftsFreeType := TtsFontGeneratorFreeType.Create(ftsContext);
{
pp := TtsPostProcessFillColor.Create(tsColor4f(0.0, 0.0, 0.0, 1.0), TS_MODES_MODULATE_ALPHA, TS_CHANNELS_RGBA);
pp.AddUsageRange(tsUsageInclude, #$0000, #$FFFF);
ftsGenerator.AddPostProcessStep(pp);

pp := TtsPostProcessShadow.Create(3, 0, 2, 2, tsColor4f(1.0, 0.0, 1.0, 0.05));
pp.AddUsageRange(tsUsageInclude, #$0000, #$FFFF);
ftsGenerator.AddPostProcessStep(pp);
}
try
ftsFont1 := ftsGenerator.GetFontByName('Calibri', ftsRenderer, 35, [tsStyleUnderline, tsStyleStrikeout], tsAANormal);
ftsFont2 := ftsGenerator.GetFontByName('Calibri', ftsRenderer, 20, [], tsAANormal);
ftsFont3 := ftsFreeType.GetFontByFile('calibri.ttf', ftsRenderer, 35, [tsStyleUnderline, tsStyleStrikeout], tsAANormal);
except
on e: EtsException do
MessageDlg('Error', e.Message, mtError, [mbOK], 0);
end;
{$ENDIF}
end;

procedure TMainForm.FormDestroy(Sender: TObject);
begin
{$IFDEF USE_OLD_TS}
tsFontDestroy(ftsFont);
tsContextDestroy(ftsContext);
{$ELSE}
FreeAndNil(ftsFont1);
FreeAndNil(ftsFont2);
FreeAndNil(ftsGenerator);
FreeAndNil(ftsFreeType);
FreeAndNil(ftsRenderer);
FreeAndNil(ftsContext);
{$ENDIF}
end;

procedure TMainForm.FormPaint(Sender: TObject);
begin
Render;
end;

procedure TMainForm.Render;
var
block: TtsTextBlock;
t: QWord;
dif: Integer;
begin
t := GetTickCount64;
if (fFrameTime <> 0) then begin
dif := t - fFrameTime;
inc(fFrameCount, 1);
inc(fSecTime, dif);
if (fSecTime > 1000) then begin
Caption := IntToStr(fFrameCount) + ' FPS';
fFrameCount := 0;
dec(fSecTime, 1000);
end;
end;
fFrameTime := t;

glViewport(0, 0, ClientWidth, ClientHeight);
glClearColor(0, 0, 0, 0);
glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);

glMatrixMode(GL_PROJECTION);
glLoadIdentity;
glOrtho(0, ClientWidth, ClientHeight, 0, -10, 10);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity;

glEnable(GL_BLEND);
glcBlendFunc(TglcBlendMode.bmAlphaBlend);

{$IFDEF USE_OLD_TS}
tsTextBeginBlock(0, 0, ClientWidth, ClientHeight, TS_ALIGN_BLOCK);
tsTextOutA(TEST_STRING);
tsTextEndBlock;
{$ELSE}
block := ftsRenderer.BeginBlock(0, 0, ClientWidth, ClientHeight, [tsBlockFlagWordWrap]);
try
//block.HorzAlign := tsHorzAlignJustify;

block.ChangeFont(ftsFont1);
block.ChangeColor(tsColor4f(1.0, 1.0, 1.0, 1.0));
block.TextOutA(TEST_STRING + sLineBreak + sLineBreak);

block.ChangeFont(ftsFont3);
block.ChangeColor(tsColor4f(1.0, 1.0, 1.0, 1.0));
block.TextOutA(TEST_STRING);
finally
ftsRenderer.EndBlock(block);
end;
{$ENDIF}
fContext.SwapBuffers;
end;

procedure TMainForm.ApplicationPropertiesIdle(Sender: TObject; var Done: Boolean);
begin
Render;
Done := false;
end;

end.


+ 0
- 3649
old/TextSuite.pas
Разница между файлами не показана из-за своего большого размера
Просмотреть файл


+ 0
- 142
old/TextSuiteCPUUtils.pas Просмотреть файл

@@ -1,143 +0,0 @@
{
TextSuite (C) Steffen Xonna (aka Lossy eX)
http://www.opengl24.de/
For copyright informations see file copyright.txt.
}

{$I TextSuiteOptions.inc}

unit TextSuiteCPUUtils;

{$ifdef TS_PURE_PASCAL}
{$message fatal 'This unit is''t compatible to the flag TS_PURE_PASCAL.'}
{$endif}

interface


var
supportFPU,
supportCMOV,
supportMMX,
supportMMX_EXT,
supportSSE,
supportSSE2,
support3DNow,
support3DNow_EXT,
supportSSE3,
supportSSSE3
: ByteBool;


procedure ReadCPUFlags;

function GetSSESafeMem(Size: Cardinal): Pointer;
function GetSSESafeAddr(Addr: Pointer): Pointer;


implementation


const
BIT_FPU = 1 shl 0;
BIT_CMOV = 1 shl 15;
BIT_MMX = 1 shl 23;
BIT_SSE = 1 shl 25;
BIT_SSE2 = 1 shl 26;
BIT_3DNOW_EXT = 1 shl 30;
BIT_3DNOW = 1 shl 31;

BIT_SSE3 = 1 shl 0;
BIT_SSSE3 = 1 shl 9;


procedure ReadCPUFlags;
asm
pushfd
pop eax // copy EEFlags to eax
mov edx, eax // copy to edx

xor eax, $00200000 // clear bit 21
push eax
popfd // restore to EEFlags

pushfd
pop eax // copy EEFlags to eax
xor eax, edx // test if flags hav changed
jnz @@supportCPUID

ret

@@supportCPUID:

push ebx // save ebx

mov eax, 1 // function 1
cpuid

// test flags
test edx, BIT_FPU
setnz [supportFPU] // FPU supported

test edx, BIT_CMOV
setnz [supportCMOV] // CMOV supported

test edx, BIT_MMX
setnz [supportMMX] // MMX supported

test edx, BIT_SSE
setnz [supportSSE] // SSE supported

test edx, BIT_SSE2
setnz [supportSSE2] // SSE2 supported

test ecx, BIT_SSE3
setnz [supportSSE3] // SSE3 supported

test ecx, BIT_SSSE3
setnz [supportSSSE3] // SSSE3 supported

// test extended functions
mov eax, $80000000
cpuid
cmp eax, $80000000
jbe @@no_ext_functions

mov eax, $80000001
cpuid

test edx, BIT_3DNOW
setnz [support3DNow] // 3DNow supported

test edx, BIT_3DNOW_EXT
setnz [support3DNow_EXT] // 3DNowExt supported


@@no_ext_functions:

pop ebx // restore ebx

@@end:
end;


function GetSSESafeMem(Size: Cardinal): Pointer;
begin
GetMem(Result, Size + $F);
end;


function GetSSESafeAddr(Addr: Pointer): Pointer;
asm
test eax, $F // test if one of the last bits are set
jz @@end // address is allways 16 Byte aligned
or eax, $F // fill the last 4 bits
inc eax // add 1
@@end:
end;


end.

+ 0
- 5761
old/TextSuiteClasses.pas
Разница между файлами не показана из-за своего большого размера
Просмотреть файл


+ 0
- 866
old/TextSuiteImports.pas Просмотреть файл

@@ -1,867 +0,0 @@
{
TextSuite (C) Steffen Xonna (aka Lossy eX)
http://www.opengl24.de/
For copyright informations see file copyright.txt.
}

{$I TextSuiteOptions.inc}

unit TextSuiteImports;

interface

uses
TextSuite;

type
DWORD = Cardinal;
PDWORD = ^DWORD;

// *** Global Functions ***
{$IFDEF WINDOWS}
const
Kernel32 = 'kernel32.dll';

function LoadLibrary(lpFileName: pAnsiChar): Pointer; stdcall; external Kernel32 name 'LoadLibraryA';
function FreeLibrary(hModule: Pointer): Pointer; stdcall; external Kernel32 name 'FreeLibrary';
function GetProcAddress(hModule: Pointer; lpProcName: pAnsiChar): Pointer; stdcall; external Kernel32 name 'GetProcAddress';
{$ELSE}
const
LibraryLib = {$IFDEF Linux} 'libdl.so.2'{$ELSE} 'c'{$ENDIF};

RTLD_LAZY = $001;

function dlopen(Name: pAnsiChar; Flags: LongInt): Pointer; cdecl; external LibraryLib name 'dlopen';
function dlclose(Lib: Pointer): LongInt; cdecl; external LibraryLib name 'dlclose';
function dlsym(Lib: Pointer; Name: pAnsiChar): Pointer; cdecl; external LibraryLib name 'dlsym';
{$ENDIF}


{$IFDEF WINDOWS}
function GetCurrentThreadId: DWORD; stdcall; external Kernel32 name 'GetCurrentThreadId';
{$ENDIF}



// *** OpenGL ***
function Init_OpenGL: Boolean;
procedure Quit_OpenGL;

const
{$IFDEF WINDOWS}
LIB_OPENGL = 'opengl32.dll';
{$ELSE}
LIB_OPENGL = 'libGL.so.1';
{$ENDIF}

GL_TEXTURE_2D = $0DE1;
GL_RGBA = $1908;
GL_UNSIGNED_BYTE = $1401;
GL_NEAREST = $2600;
GL_LINEAR = $2601;
GL_TEXTURE_MAG_FILTER = $2800;
GL_TEXTURE_MIN_FILTER = $2801;

GL_LINES = $0001;
GL_QUADS = $0007;

GL_COMPILE = $1300;


var
OpenGL_initialized: Boolean;
Library_OpenGL: Pointer;

glEnable: procedure(cap: Cardinal); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
glDisable: procedure(cap: Cardinal); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}

glColor4f: procedure(red, green, blue, alpha: Single); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}

glGenTextures: procedure(n: Integer; textures: PCardinal); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
glDeleteTextures: procedure(n: Integer; const textures: PCardinal); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
glBindTexture: procedure(target: Cardinal; texture: Cardinal); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
glTexParameteri: procedure(target: Cardinal; pname: Cardinal; param: Integer); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
glTexImage2D: procedure(target: Cardinal; level: Integer; internalformat: Integer; width: Integer; height: Integer; border: Integer; format: Cardinal; _type: Cardinal; const pixels: Pointer); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
glTexSubImage2D: procedure(target: Cardinal; level: Integer; xoffset: Integer; yoffset: Integer; width: Integer; height: Integer; format: Cardinal; _type: Cardinal; const pixels: Pointer); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}

glBegin: procedure(mode: Cardinal); {$IFNDEF CLR}{$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}{$ENDIF}
glEnd: procedure(); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
glTexCoord2f: procedure(s: Single; t: Single); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
glTexCoord2fv: procedure(v: Pointer); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
glVertex2f: procedure(x: Single; y: Single); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
glVertex2fv: procedure(v: Pointer); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
glVertex2iv: procedure(v: Pointer); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}

glGenLists: function(range: Integer): Cardinal; {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
glDeleteLists: procedure(list: Cardinal; range: Integer); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
glCallList: procedure(list: Cardinal); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
glNewList: procedure(list: Cardinal; mode: Cardinal); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}
glEndList: procedure(); {$IFDEF WINDOWS}stdcall; {$ELSE}cdecl; {$ENDIF}



// *** Windows GDI ***
function Init_GDI: Boolean;
procedure Quit_GDI;

type
HDC = Cardinal;
HFONT = Cardinal;
HGDIOBJ = Cardinal;

{$IFDEF CPU64}
{$PACKRECORDS 8}
{$ENDIF}

TFixed = packed record
fract: Word;
value: Smallint;
end;

TMat2 = packed record
eM11: TFixed;
eM12: TFixed;
eM21: TFixed;
eM22: TFixed;
end;
PMat2 = ^TMat2;

TLogFontA = record
lfHeight: Longint;
lfWidth: Longint;
lfEscapement: Longint;
lfOrientation: Longint;
lfWeight: Longint;
lfItalic: Byte;
lfUnderline: Byte;
lfStrikeOut: Byte;
lfCharSet: Byte;
lfOutPrecision: Byte;
lfClipPrecision: Byte;
lfQuality: Byte;
lfPitchAndFamily: Byte;
lfFaceName: array[0..31] of AnsiChar;
end;
PLogFontA = ^TLogFontA;

TTextMetricW = record
tmHeight: Longint;
tmAscent: Longint;
tmDescent: Longint;
tmInternalLeading: Longint;
tmExternalLeading: Longint;
tmAveCharWidth: Longint;
tmMaxCharWidth: Longint;
tmWeight: Longint;
tmOverhang: Longint;
tmDigitizedAspectX: Longint;
tmDigitizedAspectY: Longint;
tmFirstChar: WideChar;
tmLastChar: WideChar;
tmDefaultChar: WideChar;
tmBreakChar: WideChar;
tmItalic: Byte;
tmUnderlined: Byte;
tmStruckOut: Byte;
tmPitchAndFamily: Byte;
tmCharSet: Byte;
end;
PTextMetricW = ^TTextMetricW;

TGlyphMetrics = record
gmBlackBoxX: Cardinal;
gmBlackBoxY: Cardinal;
gmptGlyphOrigin: tsPoint;
gmCellIncX: Smallint;
gmCellIncY: Smallint;
end;
PGlyphMetrics = ^TGlyphMetrics;

TGCPResultsW = record
lStructSize: DWORD;
lpOutString: PWideChar;
lpOrder: PDWORD;
lpDx: PInteger;
lpCaretPos: PInteger;
lpClass: PChar;
lpGlyphs: PCardinal;
nGlyphs: Cardinal;
nMaxFit: Cardinal;
end;
PGCPResultsW = ^TGCPResultsW;

TPanose = record
bFamilyType: Byte;
bSerifStyle: Byte;
bWeight: Byte;
bProportion: Byte;
bContrast: Byte;
bStrokeVariation: Byte;
bArmStyle: Byte;
bLetterform: Byte;
bMidline: Byte;
bXHeight: Byte;
end;
PPanose = ^TPanose;

TOutlineTextmetricW = record
otmSize: LongWord;
otmTextMetrics: TTextMetricW;
otmFiller: Byte;
otmPanoseNumber: TPanose;
otmfsSelection: LongWord;
otmfsType: LongWord;
otmsCharSlopeRise: Integer;
otmsCharSlopeRun: Integer;
otmItalicAngle: Integer;
otmEMSquare: LongWord;
otmAscent: Integer;
otmDescent: Integer;
otmLineGap: LongWord;
otmsCapEmHeight: LongWord;
otmsXHeight: LongWord;
otmrcFontBox: tsRect;
otmMacAscent: Integer;
otmMacDescent: Integer;
otmMacLineGap: LongWord;
otmusMinimumPPEM: LongWord;
otmptSubscriptSize: tsPoint;
otmptSubscriptOffset: tsPoint;
otmptSuperscriptSize: tsPoint;
otmptSuperscriptOffset: tsPoint;
otmsStrikeoutSize: LongWord;
otmsStrikeoutPosition: Integer;
otmsUnderscoreSize: Integer;
otmsUnderscorePosition: Integer;
otmpFamilyName: PWideChar;
otmpFaceName: PWideChar;
otmpStyleName: PWideChar;
otmpFullName: PWideChar;
end;
POutlineTextmetricW = ^TOutlineTextmetricW;

{$IFDEF CPU64}
{$PACKRECORDS 4}
{$ENDIF}

const
LIB_GDI32 = 'gdi32.dll';
LIB_KERNEL32 = 'kernel32.dll';

GDI_ERROR = DWORD($FFFFFFFF);

FW_NORMAL = 400;
FW_BOLD = 700;

DEFAULT_CHARSET = 1;

NONANTIALIASED_QUALITY = 3;
ANTIALIASED_QUALITY = 4;

GGO_METRICS = 0;
GGO_BITMAP = 1;
GGO_GRAY8_BITMAP = 6;
GGO_GLYPH_INDEX = $80;

FR_PRIVATE = $10;
FR_NOT_ENUM = $20;

LOCALE_USER_DEFAULT = $0400;
LOCALE_ILANGUAGE = $1;

GCP_MAXEXTENT = $100000;

TMPF_FIXED_PITCH = 1;


var
GDI_initialized: Boolean;
Library_GDI32: Pointer;
Library_KERNEL32: Pointer;

CreateFontIndirectA: function (const p1: TLogFontA): HFONT; stdcall;

AddFontResourceA: function(Filename: PAnsiChar): Integer; stdcall;
AddFontResourceExA: function(Filename: PAnsiChar; Flag: DWORD; pdv: Pointer): Integer; stdcall;
AddFontMemResourceEx: function(pbFont: Pointer; cbFont: DWORD; pdv: Pointer; pcFonts: PDWORD): THandle; stdcall;
RemoveFontResourceA: function(Filename: PAnsiChar): Boolean; stdcall;
RemoveFontResourceExA: function(filename: PAnsiChar; Flag: DWORD; pdv: Pointer): Boolean; stdcall;
RemoveFontMemResourceEx: function(fh: THandle): Boolean; stdcall;

GetTextMetricsW: function(DC: HDC; var TM: TTextMetricW): Boolean; stdcall;
//GetGlyphOutlineA: function(DC: HDC; uChar, uFormat: Word; const lpgm: TGlyphMetrics; cbBuffer: DWORD; lpvBuffer: Pointer; const lpmat2: TMat2): DWORD; stdcall;
GetGlyphOutlineA: function(DC: HDC; uChar, uFormat: Cardinal; lpgm: PGlyphMetrics; cbBuffer: DWORD; lpvBuffer: Pointer; lpmat2: PMat2): DWORD; stdcall;

GetCharacterPlacementW: function(DC: HDC; Str: PWideChar; Count, MaxExtent: Integer; Result: PGCPResultsW; Flags: DWORD): DWORD; stdcall;
GetFontData: function(DC: HDC; TableName, Offset: DWORD; Buffer: Pointer; Data: DWORD): DWORD; stdcall;

CreateCompatibleDC: function(DC: HDC): HDC; stdcall;
DeleteDC: function(DC: HDC): Boolean; stdcall;
SelectObject: function(DC: HDC; p2: HGDIOBJ): HGDIOBJ; stdcall;
DeleteObject: function(p1: HGDIOBJ): Boolean; stdcall;

GetLocaleInfoA: function(Locale: DWORD; LCType: DWORD; lpLCData: pAnsiChar; cchData: Integer): Integer; stdcall;

GetOutlineTextMetricsW: function(DC: HDC; p2: LongWord; var OTMetricStructs: TOutlineTextmetricW): LongWord; stdcall;

// *** SDL globals ***
function Init_SDL: Boolean;
procedure Quit_SDL;

type
PSDL_Color = ^TSDL_Color;
TSDL_Color = record
r: Byte;
g: Byte;
b: Byte;
unused: Byte;
end;

TSDL_Rect = record
X: Smallint;
Y: Smallint;
Width: Word;
Height: Word;
end;

PSDL_ColorArray = ^TSDL_ColorArray;
TSDL_ColorArray = array[0..65000] of TSDL_Color;

PSDL_Palette = ^TSDL_Palette;
TSDL_Palette = record
ncolors: Integer;
colors: PSDL_ColorArray;
end;

PSDL_PixelFormat = ^TSDL_PixelFormat;
TSDL_PixelFormat = record
Palette: PSDL_Palette;
BitsPerPixel: Byte;
BytesPerPixel: Byte;
Rloss: Byte;
Gloss: Byte;
Bloss: Byte;
Aloss: Byte;
Rshift: Byte;
Gshift: Byte;
Bshift: Byte;
Ashift: Byte;
RMask: Cardinal;
GMask: Cardinal;
BMask: Cardinal;
AMask: Cardinal;
Colorkey: Cardinal;
Alpha: Byte;
end;


PSDL_Surface = ^TSDL_Surface;
TSDL_Surface = record
Flags: Cardinal;
Format: PSDL_PixelFormat;
Width: Integer;
Height: Integer;
Pitch: Word;
Pixels: Pointer;
Offset: Integer;
HWDdata: Pointer;
ClipRect: TSDL_Rect;
Unused1: Cardinal;
Locked: Cardinal;
Blitmap: Pointer;
FormatVersion: Cardinal;
RefCount: Integer;
end;


const
{$IFDEF WINDOWS}
LIB_SDL = 'SDL.dll';
{$ELSE}
LIB_SDL = 'libSDL.so';
LIB_SDL_VERSION = 'libSDL-1.2.so.0';
{$ENDIF}

SDL_SWSURFACE = $00000000;
var
Library_SDL: Pointer;

SDL_FreeSurface: procedure(surface: PSDL_Surface); cdecl;
SDL_ConvertSurface: function(Source: PSDL_Surface; Format: PSDL_PixelFormat; flags: Cardinal): PSDL_Surface; cdecl;



// *** SDL_TTF ***
function Init_SDL_TTF: Boolean;
procedure Quit_SDL_TTF;

type
PTTF_Font = ^TTTF_font;
TTTF_Font = record end;


const
{$IFDEF WINDOWS}
LIB_SDL_TTF = 'SDL_ttf.dll';
{$ELSE}
LIB_SDL_TTF = 'libSDL_ttf.so';
LIB_SDL_TTF_VERSION = 'libSDL_ttf-2.0.so.0';
{$ENDIF}

TTF_STYLE_NORMAL = $00;
TTF_STYLE_BOLD = $01;
TTF_STYLE_ITALIC = $02;
// TTF_STYLE_UNDERLINE = $04;

// ZERO WIDTH NO-BREAKSPACE (Unicode byte order mark)
// UNICODE_BOM_NATIVE = $FEFF;
// UNICODE_BOM_SWAPPED = $FFFE;

var
SDL_TTF_initialized: Boolean;
Library_SDL_TTF: Pointer;

TTF_Init: function: Integer; cdecl;
TTF_WasInit: function: Integer; cdecl;
TTF_OpenFont: function(const Filename: pAnsiChar; PTSize: Integer): PTTF_Font; cdecl;
TTF_CloseFont: procedure(Font: PTTF_Font); cdecl;

TTF_GetFontStyle: function(Font: PTTF_Font): Integer; cdecl;
TTF_SetFontStyle: procedure(Font: PTTF_Font; Style: Integer); cdecl;

TTF_FontAscent: function(Font: PTTF_Font) : Integer; cdecl;
TTF_FontDescent: function(Font: PTTF_Font) : Integer; cdecl;
TTF_FontLineSkip: function(Font: PTTF_Font): Integer; cdecl;
TTF_FontFaceIsFixedWidth: function(Font: PTTF_Font): Integer; cdecl;
TTF_FontFaceFamilyName: function(Font: PTTF_Font): pAnsiChar; cdecl;
TTF_FontFaceStyleName: function(Font : PTTF_Font): pAnsiChar; cdecl;
TTF_GlyphMetrics: function(Font: PTTF_Font; CharCode: WORD; var MinX: Integer; var MaxX: Integer; var MinY: Integer; var MaxY: Integer; var Advance: Integer): Integer; cdecl;

TTF_RenderGlyph_Solid: function(Font: PTTF_Font; Char: WORD; const ForeGround: TSDL_Color): PSDL_Surface; cdecl;
TTF_RenderGlyph_Shaded: function(Font: PTTF_Font; Char: WORD; const ForeGround: TSDL_Color; const BackGround: TSDL_Color): PSDL_Surface; cdecl;



// *** SDL_IMAGE ***
function Init_SDL_IMAGE: Boolean;
procedure Quit_SDL_IMAGE;

const
{$IFDEF WINDOWS}
LIB_SDL_IMAGE = 'SDL_Image.dll';
{$ELSE}
LIB_SDL_IMAGE = 'libSDL_image.so';
LIB_SDL_IMAGE_VERSION = 'libSDL_image-1.2.so.0';
{$ENDIF}

var
SDL_IMAGE_initialized: Boolean;
Library_SDL_IMAGE: Pointer;

IMG_Load: function(const _file: PAnsiChar): PSDL_Surface; cdecl;


implementation


function GetLibraryProc(hLibrary: Pointer; ProcName: pAnsiChar): Pointer;
begin
{$IFDEF WINDOWS}
Result := GetProcAddress(hLibrary, ProcName);
{$ELSE}
Result := dlsym(hLibrary, ProcName);
{$ENDIF}
end;


function GetOpenGLLibraryProc(hLibrary: Pointer; ProcName: pAnsiChar): Pointer;
begin
Result := GetLibraryProc(hLibrary, ProcName);
end;


// *** OpenGL ***

function Init_OpenGL: Boolean;
begin
if Library_OpenGL = nil then begin
{$IFDEF WINDOWS}
Library_OpenGL := LoadLibrary(LIB_OPENGL);
{$ELSE}
Library_OpenGL := dlopen(LIB_OPENGL, RTLD_LAZY);
{$ENDIF}
end;

if Library_OpenGL <> nil then begin
glEnable := GetOpenGLLibraryProc(Library_OpenGL, 'glEnable');
glDisable := GetOpenGLLibraryProc(Library_OpenGL, 'glDisable');
glColor4f := GetOpenGLLibraryProc(Library_OpenGL, 'glColor4f');
glGenTextures := GetOpenGLLibraryProc(Library_OpenGL, 'glGenTextures');
glDeleteTextures := GetOpenGLLibraryProc(Library_OpenGL, 'glDeleteTextures');
glBindTexture := GetOpenGLLibraryProc(Library_OpenGL, 'glBindTexture');
glTexParameteri := GetOpenGLLibraryProc(Library_OpenGL, 'glTexParameteri');
glTexImage2D := GetOpenGLLibraryProc(Library_OpenGL, 'glTexImage2D');
glTexSubImage2D := GetOpenGLLibraryProc(Library_OpenGL, 'glTexSubImage2D');
glBegin := GetOpenGLLibraryProc(Library_OpenGL, 'glBegin');
glEnd := GetOpenGLLibraryProc(Library_OpenGL, 'glEnd');
glTexCoord2f := GetOpenGLLibraryProc(Library_OpenGL, 'glTexCoord2f');
glTexCoord2fv := GetOpenGLLibraryProc(Library_OpenGL, 'glTexCoord2fv');
glVertex2f := GetOpenGLLibraryProc(Library_OpenGL, 'glVertex2f');
glVertex2fv := GetOpenGLLibraryProc(Library_OpenGL, 'glVertex2fv');
glVertex2iv := GetOpenGLLibraryProc(Library_OpenGL, 'glVertex2iv');
glGenLists := GetOpenGLLibraryProc(Library_OpenGL, 'glGenLists');
glDeleteLists := GetOpenGLLibraryProc(Library_OpenGL, 'glDeleteLists');
glCallList := GetOpenGLLibraryProc(Library_OpenGL, 'glCallList');
glNewList := GetOpenGLLibraryProc(Library_OpenGL, 'glNewList');
glEndList := GetOpenGLLibraryProc(Library_OpenGL, 'glEndList');
end;

OpenGL_initialized :=
(Addr(glEnable) <> nil) and
(Addr(glDisable) <> nil) and
(Addr(glColor4f) <> nil) and
(Addr(glGenTextures) <> nil) and
(Addr(glDeleteTextures) <> nil) and
(Addr(glBindTexture) <> nil) and
(Addr(glTexParameteri) <> nil) and
(Addr(glTexImage2D) <> nil) and
(Addr(glTexSubImage2D) <> nil) and
(Addr(glBegin) <> nil) and
(Addr(glEnd) <> nil) and
(Addr(glTexCoord2f) <> nil) and
(Addr(glTexCoord2fv) <> nil) and
(Addr(glVertex2f) <> nil) and
(Addr(glVertex2fv) <> nil) and
(Addr(glVertex2iv) <> nil) and
(Addr(glGenLists) <> nil) and
(Addr(glDeleteLists) <> nil) and
(Addr(glCallList) <> nil) and
(Addr(glNewList) <> nil) and
(Addr(glEndList) <> nil);

Result := OpenGL_initialized;
end;


procedure Quit_OpenGL;
begin
glEnable := nil;
glDisable := nil;
glColor4f := nil;
glGenTextures := nil;
glDeleteTextures := nil;
glBindTexture := nil;
glTexParameteri := nil;
glTexImage2D := nil;
glTexSubImage2D := nil;
glBegin := nil;
glEnd := nil;
glTexCoord2f := nil;
glTexCoord2fv := nil;
glVertex2f := nil;
glVertex2fv := nil;
glVertex2iv := nil;
glGenLists := nil;
glDeleteLists := nil;
glCallList := nil;
glNewList := nil;
glEndList := nil;

if Library_OpenGL <> nil then begin
{$IFDEF WINDOWS}
FreeLibrary(Library_OpenGL);
Library_OpenGL := nil;
{$ELSE}
dlclose(Library_OpenGL);
Library_OpenGL := nil;
{$ENDIF}
end;

OpenGL_initialized := False;
end;


// *** Windows GDI globals ***
function Init_GDI: Boolean;
begin
if Library_GDI32 = nil then begin
{$IFDEF WINDOWS}
Library_GDI32 := LoadLibrary(LIB_GDI32);
// {$ELSE}
// Library_GDI32 := nil; //dlopen(LIB_GDI, RTLD_LAZY);
{$ENDIF}
end;

if Library_GDI32 <> nil then begin
CreateFontIndirectA := GetLibraryProc(Library_GDI32, 'CreateFontIndirectA');

AddFontResourceA := GetLibraryProc(Library_GDI32, 'AddFontResourceA');
AddFontResourceExA := GetLibraryProc(Library_GDI32, 'AddFontResourceExA');
AddFontMemResourceEx := GetLibraryProc(Library_GDI32, 'AddFontMemResourceEx');
RemoveFontResourceA := GetLibraryProc(Library_GDI32, 'RemoveFontResourceA');
RemoveFontResourceExA := GetLibraryProc(Library_GDI32, 'RemoveFontResourceExA');
RemoveFontMemResourceEx := GetLibraryProc(Library_GDI32, 'RemoveFontMemResourceEx');

GetTextMetricsW := GetLibraryProc(Library_GDI32, 'GetTextMetricsW');
GetGlyphOutlineA := GetLibraryProc(Library_GDI32, 'GetGlyphOutlineA');

GetCharacterPlacementW := GetLibraryProc(Library_GDI32, 'GetCharacterPlacementW');
GetFontData := GetLibraryProc(Library_GDI32, 'GetFontData');

CreateCompatibleDC := GetLibraryProc(Library_GDI32, 'CreateCompatibleDC');
DeleteDC := GetLibraryProc(Library_GDI32, 'DeleteDC');
SelectObject := GetLibraryProc(Library_GDI32, 'SelectObject');
DeleteObject := GetLibraryProc(Library_GDI32, 'DeleteObject');

GetOutlineTextMetricsW := GetLibraryProc(Library_GDI32, 'GetOutlineTextMetricsW');
end;

if Library_KERNEL32 = nil then begin
{$IFDEF WINDOWS}
Library_KERNEL32 := LoadLibrary(LIB_KERNEL32);
{$ENDIF}
end;

if Library_KERNEL32 <> nil then begin
GetLocaleInfoA := GetLibraryProc(Library_KERNEL32, 'GetLocaleInfoA');
end;

GDI_initialized :=
(Addr(CreateFontIndirectA) <> nil) and

((Addr(AddFontResourceA) <> nil) or
(Addr(AddFontResourceExA) <> nil)) and

((Addr(RemoveFontResourceA) <> nil) or
(Addr(RemoveFontResourceExA) <> nil)) and

(Addr(GetTextMetricsW) <> nil) and
(Addr(GetGlyphOutlineA) <> nil) and

// under 9x GetCharacterPlacementW dosn't exist
(Addr(GetCharacterPlacementW) <> nil) and
(Addr(GetFontData) <> nil) and

(Addr(CreateCompatibleDC) <> nil) and
(Addr(DeleteDC) <> nil) and
(Addr(SelectObject) <> nil) and
(Addr(DeleteObject) <> nil) and

(Addr(GetLocaleInfoA) <> nil) and

(Addr(GetOutlineTextMetricsW) <> nil);

Result := GDI_initialized;
end;


procedure Quit_GDI;
begin
CreateFontIndirectA := nil;
AddFontResourceA := nil;
AddFontResourceExA := nil;
RemoveFontResourceA := nil;
RemoveFontResourceExA := nil;
GetTextMetricsW := nil;
GetGlyphOutlineA := nil;
GetCharacterPlacementW := nil;
GetFontData := nil;
CreateCompatibleDC := nil;
DeleteDC := nil;
SelectObject := nil;
DeleteObject := nil;

if Library_GDI32 <> nil then begin
{$IFDEF WINDOWS}
FreeLibrary(Library_GDI32);
Library_GDI32 := nil;
{$ENDIF}
end;

GetLocaleInfoA := nil;

if Library_KERNEL32 <> nil then begin
{$IFDEF WINDOWS}
FreeLibrary(Library_KERNEL32);
Library_KERNEL32 := nil;
{$ENDIF}
end;

GDI_initialized := False;
end;


// *** SDL globals ***
function Init_SDL: Boolean;
begin
if Library_SDL = nil then begin
{$IFDEF WINDOWS}
Library_SDL := LoadLibrary(LIB_SDL);
{$ELSE}
Library_SDL := dlopen(LIB_SDL, RTLD_LAZY);

if Library_SDL = nil then
Library_SDL := dlopen(LIB_SDL_VERSION, RTLD_LAZY);
{$ENDIF}
end;

if Library_SDL <> nil then begin
SDL_FreeSurface := GetLibraryProc(Library_SDL, 'SDL_FreeSurface');
SDL_ConvertSurface := GetLibraryProc(Library_SDL, 'SDL_ConvertSurface');
end;

Result :=
(Addr(SDL_FreeSurface) <> nil) and
(Addr(SDL_ConvertSurface) <> nil);
end;


procedure Quit_SDL;
begin
SDL_FreeSurface := nil;
SDL_ConvertSurface := nil;

if Library_SDL <> nil then begin
{$IFDEF WINDOWS}
FreeLibrary(Library_SDL);
Library_SDL := nil;
{$ELSE}
dlclose(Library_SDL);
Library_SDL := nil;
{$ENDIF}
end;
end;


// *** SDL_TTF ***
function Init_SDL_TTF: Boolean;
begin
if Library_SDL_TTF = nil then begin
{$IFDEF WINDOWS}
Library_SDL_TTF := LoadLibrary(LIB_SDL_TTF);
{$ELSE}
Library_SDL_TTF := dlopen(LIB_SDL_TTF, RTLD_LAZY);

if Library_SDL_TTF = nil then
Library_SDL_TTF := dlopen(LIB_SDL_TTF_VERSION, RTLD_LAZY);
{$ENDIF}
end;

if Library_SDL_TTF <> nil then begin
TTF_Init := GetLibraryProc(Library_SDL_TTF, 'TTF_Init');
TTF_WasInit := GetLibraryProc(Library_SDL_TTF, 'TTF_WasInit');
TTF_OpenFont := GetLibraryProc(Library_SDL_TTF, 'TTF_OpenFont');
TTF_CloseFont := GetLibraryProc(Library_SDL_TTF, 'TTF_CloseFont');
TTF_GetFontStyle := GetLibraryProc(Library_SDL_TTF, 'TTF_GetFontStyle');
TTF_SetFontStyle := GetLibraryProc(Library_SDL_TTF, 'TTF_SetFontStyle');
TTF_FontAscent := GetLibraryProc(Library_SDL_TTF, 'TTF_FontAscent');
TTF_FontDescent := GetLibraryProc(Library_SDL_TTF, 'TTF_FontDescent');
TTF_FontLineSkip := GetLibraryProc(Library_SDL_TTF, 'TTF_FontLineSkip');
TTF_FontFaceIsFixedWidth := GetLibraryProc(Library_SDL_TTF, 'TTF_FontFaceIsFixedWidth');
TTF_FontFaceFamilyName := GetLibraryProc(Library_SDL_TTF, 'TTF_FontFaceFamilyName');
TTF_FontFaceStyleName := GetLibraryProc(Library_SDL_TTF, 'TTF_FontFaceStyleName');
TTF_GlyphMetrics := GetLibraryProc(Library_SDL_TTF, 'TTF_GlyphMetrics');
TTF_RenderGlyph_Solid := GetLibraryProc(Library_SDL_TTF, 'TTF_RenderGlyph_Solid');
TTF_RenderGlyph_Shaded := GetLibraryProc(Library_SDL_TTF, 'TTF_RenderGlyph_Shaded');
end;

SDL_TTF_initialized :=
Init_SDL and
(Addr(TTF_Init) <> nil) and
(Addr(TTF_WasInit) <> nil) and
(Addr(TTF_OpenFont) <> nil) and
(Addr(TTF_CloseFont) <> nil) and
(Addr(TTF_GetFontStyle) <> nil) and
(Addr(TTF_SetFontStyle) <> nil) and
(Addr(TTF_FontAscent) <> nil) and
(Addr(TTF_FontDescent) <> nil) and
(Addr(TTF_FontLineSkip) <> nil) and
(Addr(TTF_FontFaceIsFixedWidth) <> nil) and
(Addr(TTF_FontFaceFamilyName) <> nil) and
(Addr(TTF_FontFaceStyleName) <> nil) and
(Addr(TTF_GlyphMetrics) <> nil) and
(Addr(TTF_RenderGlyph_Solid) <> nil) and
(Addr(TTF_RenderGlyph_Shaded) <> nil);

Result := SDL_TTF_initialized;
end;


procedure Quit_SDL_TTF;
begin
TTF_Init := nil;
TTF_WasInit := nil;
TTF_OpenFont := nil;
TTF_CloseFont := nil;
TTF_GetFontStyle := nil;
TTF_SetFontStyle := nil;
TTF_FontAscent := nil;
TTF_FontDescent := nil;
TTF_FontLineSkip := nil;
TTF_FontFaceIsFixedWidth := nil;
TTF_FontFaceFamilyName := nil;
TTF_FontFaceStyleName := nil;
TTF_GlyphMetrics := nil;
TTF_RenderGlyph_Solid := nil;
TTF_RenderGlyph_Shaded := nil;

if Library_SDL_TTF <> nil then begin
{$IFDEF WINDOWS}
FreeLibrary(Library_SDL_TTF);
Library_SDL_TTF := nil;
{$ELSE}
dlclose(Library_SDl_TTF);
Library_SDL_TTF := nil;
{$ENDIF}
end;

SDL_TTF_initialized := False;
end;


// *** SDL_IMAGE ***
function Init_SDL_IMAGE: Boolean;
begin
if Library_SDL_IMAGE = nil then begin
{$IFDEF WINDOWS}
Library_SDL_IMAGE := LoadLibrary(LIB_SDL_IMAGE);
{$ELSE}
Library_SDL_IMAGE := dlopen(LIB_SDL_IMAGE, RTLD_LAZY);

if Library_SDL_IMAGE = nil then
Library_SDL_IMAGE := dlopen(LIB_SDL_IMAGE_VERSION, RTLD_LAZY);
{$ENDIF}
end;

if Library_SDL_IMAGE <> nil then begin
IMG_Load := GetLibraryProc(Library_SDL_IMAGE, 'IMG_Load');
end;

SDL_IMAGE_initialized :=
Init_SDL and
(Addr(IMG_load) <> nil);

Result := SDL_IMAGE_initialized;
end;


procedure Quit_SDL_IMAGE;
begin
IMG_Load := nil;

if Library_SDL_IMAGE <> nil then begin
{$IFDEF WINDOWS}
FreeLibrary(Library_SDL_IMAGE);
Library_SDL_IMAGE := nil;
{$ELSE}
dlclose(Library_SDL_IMAGE);
Library_SDL_IMAGE := nil;
{$ENDIF}
end;
end;

end.

+ 0
- 46
old/TextSuiteOptions.inc Просмотреть файл

@@ -1,46 +0,0 @@

{ *** options *** }

{ to use the external library }
{.$define TS_EXTERN_STATIC}


{ to disable the assembler code and use pure pascal code instead.
if you have problem with some older compiler or runtime errors.
But. This can decrease the speed of some operations. }
{.$define TS_PURE_PASCAL}



{ *** important seetings. Don't touch it! *** }
{$IFDEF FPC}
{$MODE Delphi}

{$SMARTLINK ON}

{$IFDEF CPUI386}
{$DEFINE CPU386}
{$ASMMODE INTEL}
{$ELSE}
{$define TS_PURE_PASCAL}
{$ENDIF}

{$IFNDEF WINDOWS}
{$LINKLIB c}
{$ENDIF}
{$ENDIF}


{$BOOLEVAL OFF} // short boolean eval
{$LONGSTRINGS ON} // huge strings
{$EXTENDEDSYNTAX ON} // extended syntax
{$ALIGN ON} // Alignment
{$TYPEDADDRESS OFF} // Typed addresses with @

{$IFNDEF FPC}
{$OPTIMIZATION ON} // O+ Optimizations
{ $ASSERTIONS OFF} // C-
{ $RANGECHECKS OFF} // R-
{ $STACKFRAMES OFF} // W-
{ $OVERFLOWCHECKS OFF} // Q-
{$ENDIF}

+ 0
- 397
old/TextSuitePostProcess.pas Просмотреть файл

@@ -1,398 +0,0 @@
{
TextSuite (C) Steffen Xonna (aka Lossy eX)
http://www.opengl24.de/
For copyright informations see file copyright.txt.
}

{$I TextSuiteOptions.inc}

unit TextSuitePostProcess;

interface

uses
TextSuite,
TextSuiteClasses;


type
// ** Post Processing FillColor **
TtsPostFillColor = class(TtsPostProcessStep)
protected
fRed: Single;
fGreen: Single;
fBlue: Single;
fAlpha: Single;
fLuminance: Single;
fChannelMask: tsBitmask;

fModes: TtsImageModes;

procedure PostProcess(const CharImage: TtsImage; const Char: TtsChar); override;
public
constructor Create(Red, Green, Blue, Alpha: Single; ChannelMask: tsBitmask; Modes: TtsImageModes);
end;


// ** Post Processing FillPattern **
TtsPostFillPattern = class(TtsPostProcessStep)
protected
fPattern: TtsImage;
fX: Integer;
fY: Integer;
fChannelMask: tsBitmask;
fModes: TtsImageModes;

procedure PostProcess(const CharImage: TtsImage; const Char: TtsChar); override;
public
constructor Create(Pattern: TtsImage; X, Y: Integer; ChannelMask: tsBitmask; Modes: TtsImageModes);
end;


// ** Post Processing Border **
TtsPostBorderLookupFuncData = record
Kernel: TtsKernel2D;
XPos, YPos, XMax, YMax: Integer;

pData: pByte;
end;


TtsPostBorder = class(TtsPostProcessStep)
protected
fKernel: TtsKernel2D;

fRed: Single;
fGreen: Single;
fBlue: Single;
fAlpha: Single;

procedure PostProcess(const CharImage: TtsImage; const Char: TtsChar); override;
public
constructor Create(Width, Strength: Single; Red, Green, Blue, Alpha: Single);
destructor Destroy; override;
end;

// ** Post Processing Kerning **
TtsPostKerning = class(TtsPostProcessStep)
protected
procedure PostProcess(const CharImage: TtsImage; const Char: TtsChar); override;
end;


// ** Post Processing Shadow **
TtsPostShadow = class(TtsPostProcessStep)
protected
fKernel: TtsKernel1D;

fX: Integer;
fY: Integer;

fRed: Single;
fGreen: Single;
fBlue: Single;
fAlpha: Single;

procedure PostProcess(const CharImage: TtsImage; const Char: TtsChar); override;
public
constructor Create(Radius: Single; X, Y: Integer; Red, Green, Blue, Alpha: Single);
destructor Destroy; override;
end;


// ** Post Processing Custom **
TtsPostCustom = class(TtsPostProcessStep)
protected
fContext: TtsContext;
fPostProcessProc: tsPostProcessProc;
fData: Pointer;

procedure PostProcess(const CharImage: TtsImage; const Char: TtsChar); override;
public
constructor Create(Context: TtsContext; PostProcessProc: tsPostProcessProc; Data: Pointer);
end;


implementation

//uses
// TextSuiteImageUtils;


{ TtsPostFillColor }

constructor TtsPostFillColor.Create(Red, Green, Blue, Alpha: Single; ChannelMask: tsBitmask; Modes: TtsImageModes);
begin
inherited Create;

fRed := Red;
fGreen := Green;
fBlue := Blue;
fAlpha := Alpha;
fChannelMask := ChannelMask;
fModes := Modes;
end;


procedure TtsPostFillColor.PostProcess(const CharImage: TtsImage; const Char: TtsChar);
begin
if CharImage <> nil then
CharImage.FillColor(fRed, fGreen, fBlue, fAlpha, fChannelMask, fModes);
end;


{ TtsPostFillPattern }

constructor TtsPostFillPattern.Create(Pattern: TtsImage; X, Y: Integer; ChannelMask: tsBitmask; Modes: TtsImageModes);
begin
inherited Create;

fPattern := Pattern;
fX := X;
fY := Y;
fChannelMask := ChannelMask;
fModes := Modes;
end;


procedure TtsPostFillPattern.PostProcess(const CharImage: TtsImage; const Char: TtsChar);
begin
if CharImage <> nil then
CharImage.FillPattern(fPattern, fX, fY, fChannelMask, fModes);
end;



{ TtsPostBorder }

constructor TtsPostBorder.Create(Width, Strength, Red, Green, Blue, Alpha: Single);
begin
inherited Create;

fKernel := TtsKernel2D.Create(Width, Strength);

fRed := Red;
fGreen := Green;
fBlue := Blue;
fAlpha := Alpha;
end;


function BorderLookupMax(var Data: TtsPostBorderLookupFuncData): Byte;
var
Idx: Integer;
Temp, TempValue: Single;
pTempData: pByte;
begin
TempValue := 0;

with Data, Data.Kernel do begin
for Idx := 0 to ItemCount - 1 do
with Items[Idx] do
if ((XPos + OffsetX >= 0) and (XPos + OffsetX < XMax) and
(YPos + OffsetY >= 0) and (YPos + OffsetY < YMax)) then begin
pTempData := pData;

Inc(pTempData, DataOffset);

// there is no value
if pTempData^ = $00 then
Continue;

// calculate pixel
Temp := pTempData^ * Value;
if (Temp > TempValue) then
TempValue := Temp;

// there is nothing greater than this
if pTempData^ = $FF then
Break;
end;
end;

Result := Round(TempValue);
end;


destructor TtsPostBorder.Destroy;
begin
fKernel.Free;

inherited;
end;


procedure TtsPostBorder.PostProcess(const CharImage: TtsImage; const Char: TtsChar);
var
OriginalImage: TtsImage;

X, Y: Integer;
pSource, pDest: ptsColor;

Data: TtsPostBorderLookupFuncData;
begin
if CharImage <> nil then begin
// Make image geater
CharImage.Resize(CharImage.Width + fKernel.SizeX * 2, CharImage.Height + fKernel.SizeY * 2, fKernel.SizeX, fKernel.SizeY);

// Create copy of Image
OriginalImage := TtsImage.Create;
try
OriginalImage.AssignFrom(CharImage);
CharImage.FillColor(fRed, fGreen, fBlue, fAlpha, TS_CHANNELS_RGBA, cModesReplace);

fKernel.UpdateDataOffset(4, OriginalImage.Width * 4);

Data.Kernel := fKernel;
Data.XMax := OriginalImage.Width;
Data.YMax := OriginalImage.Height;

for Y := 0 to OriginalImage.Height - 1 do begin
pSource := OriginalImage.ScanLine[Y];
pDest := CharImage.ScanLine[Y];

Data.pData := @(pSource^.Alpha);
Data.YPos := Y;

for X := 0 to OriginalImage.Width - 1 do begin
Data.XPos := X;

pDest^.Alpha := Round(fAlpha * BorderLookupMax(Data));

Inc(Data.pData, 4);
Inc(pDest);
end;
end;

// Blend OriginalImage over CharImage (shadow)
CharImage.BlendImage(OriginalImage, 0, 0);
finally
OriginalImage.Free;
end;
end;

// Set Char Data
Char.GlyphRect.Left := Char.GlyphRect.Left + fKernel.SizeX - fKernel.MidSizeX;
Char.GlyphRect.Right := Char.GlyphRect.Right + fKernel.SizeX + fKernel.MidSizeX;

Char.GlyphRect.Top := Char.GlyphRect.Top + fKernel.SizeY - fKernel.MidSizeY;
Char.GlyphRect.Bottom := Char.GlyphRect.Bottom + fKernel.SizeY + fKernel.MidSizeY;

Char.GlyphOriginY := Char.GlyphOriginY + fKernel.MidSizeY;
Char.Advance := Char.Advance + fKernel.MidSizeX;
end;


{ TtsPostKerning }

procedure TtsPostKerning.PostProcess(const CharImage: TtsImage; const Char: TtsChar);
begin
// if CharImage <> nil then
// Char.CalculateKerningData(CharImage);
end;


{ TtsPostShadow }

constructor TtsPostShadow.Create(Radius: Single; X, Y: Integer; Red, Green, Blue, Alpha: Single);
begin
inherited Create;

fKernel := TtsKernel1D.Create(Radius, 0);

fX := X;
fY := Y;
fRed := Red;
fGreen := Green;
fBlue := Blue;
fAlpha := Alpha;
end;


destructor TtsPostShadow.Destroy;
begin
fKernel.Free;

inherited;
end;


procedure TtsPostShadow.PostProcess(const CharImage: TtsImage; const Char: TtsChar);
var
OriginalImage: TtsImage;
TempX, TempY: Integer;
begin
if CharImage <> nil then begin
OriginalImage := TtsImage.Create;
try
// backup to original
OriginalImage.AssignFrom(CharImage);

// Resizing image
CharImage.Resize(CharImage.Width + fKernel.Size * 2, CharImage.Height + fKernel.Size * 2, fKernel.Size, fKernel.Size);

// fill char image with color
CharImage.FillColor(fRed, fGreen, fBlue, fAlpha, TS_CHANNELS_RGBA, cModesNormal);

// blur charimage
CharImage.Blur(fKernel, fKernel, TS_CHANNEL_ALPHA);

TempX := fKernel.Size - fX;
TempY := fKernel.Size - fY;

// Blend OriginalImage over CharImage (shadow)
CharImage.BlendImage(OriginalImage, TempX, TempY);

// Set Chardimension
with Char.GlyphRect do begin
if TempX > 0 then begin
Left := Left + TempX;
Right := Right + TempX;
end;

if TempY > 0 then begin
Top := Top + TempY;
Bottom := Bottom + TempY;
end;
end;
finally
OriginalImage.Free;
end;
end;
end;


{ TtsPostCustom }

constructor TtsPostCustom.Create(Context: TtsContext; PostProcessProc: tsPostProcessProc; Data: Pointer);
begin
inherited Create;

fContext := Context;
fPostProcessProc := PostProcessProc;
fData := Data;
end;


procedure TtsPostCustom.PostProcess(const CharImage: TtsImage; const Char: TtsChar);
var
ImageID: tsImageID;
begin
if CharImage <> nil then begin
if fContext <> nil then begin
// temporary Add Image
ImageID := fContext.ImageAdd(CharImage);
try
fPostProcessProc(ImageID, Char.CharCode, fData);
finally
fContext.ImageDelete(ImageID);
end;
end;
end
// call without an ImageID
else fPostProcessProc(0, Char.CharCode, fData);
end;


end.

+ 0
- 366
old/TextSuiteTTFUtils.pas Просмотреть файл

@@ -1,367 +0,0 @@
{
TextSuite (C) Steffen Xonna (aka Lossy eX)
http://www.opengl24.de/
For copyright informations see file copyright.txt.
}

{$WARNINGS OFF}
{$HINTS OFF}

{$I TextSuiteOptions.inc}

unit TextSuiteTTFUtils;

interface

uses Classes;

const
NAME_ID_COPYRIGHT = 0;
NAME_ID_FACE_NAME = 1;
NAME_ID_STYLE_NAME = 2;
NAME_ID_FULL_NAME = 4;



function MakeTTTableName(ch1, ch2, ch3, ch4: Char): Cardinal;
function GetTTString(pBuffer: Pointer; BufferSize: Integer; NameID, LanguageID: Cardinal; var Text: AnsiString): Boolean;

function GetTTFontFullNameFromStream(Stream: TStream; LanguageID: Cardinal): AnsiString;
function GetTTFontFullNameFromFile(Filename: AnsiString; LanguageID: Cardinal): AnsiString;

(*
function GetTTUnicodeGlyphIndex(DC: Cardinal; ch: Word): Word;
function GetTTUnicodeCharCount(DC: Cardinal): Word;
*)

implementation


uses
SysUtils,
TextSuiteWideUtils,
TextSuiteImports;


function SWAPWORD(x: Word): Word;
{$ifdef TS_PURE_PASCAL}
begin
Result := x and $FF;
Result := Result shl 8;
Result := Result or (x shr 8);
{$else}
asm
mov dl, al
mov al, ah
mov ah, dl
{$endif}
end;


function SWAPLONG(x: Cardinal): Cardinal;
{$ifdef TS_PURE_PASCAL}
begin
Result := (x and $FF) shl 24;
x := x shr 8;

Result := Result or ((x and $FF) shl 16);
x := x shr 8;
Result := Result or ((x and $FF) shl 8);
x := x shr 8;

Result := Result or x;
{$else}
asm
mov dx, ax
shr eax, 16
mov cx, ax
mov al, dh
mov ah, dl
shl eax, 16
mov al, ch
mov ah, cl
{$endif}
end;


function MakeTTTableName(ch1, ch2, ch3, ch4: Char): Cardinal;
begin
Result := ord(ch4) shl 24 or ord(ch3) shl 16 or ord(ch2) shl 8 or ord(ch1);
end;


type
TT_OFFSET_TABLE = packed record
uMajorVersion: Word;
uMinorVersion: Word;
uNumOfTables: Word;
uSearchRange: Word;
uEntrySelector: Word;
uRangeShift: Word;
end;


TT_TABLE_DIRECTORY = packed record
TableName: Cardinal; // table name
uCheckSum: Cardinal; // Check sum
uOffset: Cardinal; // Offset from beginning of file
uLength: Cardinal; // length of the table in bytes
end;


TT_NAME_TABLE_HEADER = packed record
uFSelector: Word; //format selector. Always 0
uNRCount: Word; //Name Records count
uStorageOffset: Word; //Offset for strings storage, from start of the table
end;

TT_NAME_RECORD = packed record
uPlatformID: Word;
uEncodingID: Word;
uLanguageID: Word;
uNameID: Word;
uStringLength: Word;
uStringOffset: Word; //from start of storage area
end;


const
PLATFORM_ID_APPLE_UNICODE = 0;
PLATFORM_ID_MACINTOSH = 1;
PLATFORM_ID_MICROSOFT = 3;


function GetTTTableData(Stream: TStream; TableName: Cardinal; pBuff: Pointer; var Size: Integer): Boolean;
var
Pos: Int64;
OffsetTable: TT_OFFSET_TABLE;
TableDir: TT_TABLE_DIRECTORY;
Idx: Integer;
begin
Result := False;

Pos := Stream.Position;

// Reading table header
Stream.Read(OffsetTable, sizeof(TT_OFFSET_TABLE));
OffsetTable.uNumOfTables := SWAPWORD(OffsetTable.uNumOfTables);
OffsetTable.uMajorVersion := SWAPWORD(OffsetTable.uMajorVersion);
OffsetTable.uMinorVersion := SWAPWORD(OffsetTable.uMinorVersion);

//check is this is a true type font and the version is 1.0
if (OffsetTable.uMajorVersion <> 1) or (OffsetTable.uMinorVersion <> 0) then
Exit;

// seaching table with name
for Idx := 0 to OffsetTable.uNumOfTables -1 do begin
Stream.Read(TableDir, sizeof(TT_TABLE_DIRECTORY));

if (TableName = TableDir.TableName) then begin
TableDir.uOffset := SWAPLONG(TableDir.uOffset);
TableDir.uLength := SWAPLONG(TableDir.uLength);

// copying tabledata
if (pBuff <> nil) and (Size >= Integer(TableDir.uLength)) then begin
Stream.Seek(TableDir.uOffset, soBeginning);
Size := Stream.Read(pBuff^, TableDir.uLength);

Result := Size = Integer(TableDir.uLength);
end else

begin
// restoring streamposition
Stream.Position := Pos;

Size := TableDir.uLength;
Result := True;
end;

break;
end;
end;
end;


function GetTTString(pBuffer: Pointer; BufferSize: Integer; NameID, LanguageID: Cardinal; var Text: AnsiString): Boolean;
var
pActBuffer: pByte;
ttNTHeader: TT_NAME_TABLE_HEADER;
ttRecord: TT_NAME_RECORD;
Idx: Integer;
Prio: Integer;

procedure ExtractName;
var
pTempBuffer: pByte;
pTemp: pWideChar;
uStringLengthH2: Word;

procedure SwapText(pText: pWideChar; Length: Word);
begin
while Length > 0 do begin
pWord(pText)^ := SWAPWORD(pWord(pText)^);
Inc(pText);
Dec(Length);
end;
end;

begin
Result := True;

ttRecord.uStringLength := SWAPWORD(ttRecord.uStringLength);
ttRecord.uStringOffset := SWAPWORD(ttRecord.uStringOffset);

uStringLengthH2 := ttRecord.uStringLength shr 1;

pTempBuffer := pBuffer;
Inc(pTempBuffer, ttNTHeader.uStorageOffset + ttRecord.uStringOffset);

// Unicode
if ((ttRecord.uPlatformID = PLATFORM_ID_MICROSOFT) and (ttRecord.uEncodingID in [0, 1])) or
((ttRecord.uPlatformID = PLATFORM_ID_APPLE_UNICODE) and (ttRecord.uEncodingID > 0)) then begin
pTemp := tsStrAlloc(uStringLengthH2);
try
// uStringLengthH2 * 2 because possible buffer overrun
Move(pTempBuffer^, pTemp^, uStringLengthH2 * 2);

SwapText(pTemp, uStringLengthH2);

WideCharLenToStrVar(pTemp, uStringLengthH2, Text);
finally
tsStrDispose(pTemp);
end;
end else

// none unicode
begin
SetLength(Text, ttRecord.uStringLength);
Move(pTempBuffer^, Text[1], ttRecord.uStringLength);
end;
end;

begin
Result := False;

pActBuffer := pBuffer;

Move(pActBuffer^, ttNTHeader, sizeof(TT_NAME_TABLE_HEADER));
inc(pActBuffer, sizeof(TT_NAME_TABLE_HEADER));

ttNTHeader.uNRCount := SWAPWORD(ttNTHeader.uNRCount);
ttNTHeader.uStorageOffset := SWAPWORD(ttNTHeader.uStorageOffset);

Prio := -1;

for Idx := 0 to ttNTHeader.uNRCount -1 do begin
Move(pActBuffer^, ttRecord, sizeof(TT_NAME_RECORD));
Inc(pActBuffer, sizeof(TT_NAME_RECORD));

ttRecord.uNameID := SWAPWORD(ttRecord.uNameID);

if ttRecord.uNameID = NameID then begin
ttRecord.uPlatformID := SWAPWORD(ttRecord.uPlatformID);
ttRecord.uEncodingID := SWAPWORD(ttRecord.uEncodingID);
ttRecord.uLanguageID := SWAPWORD(ttRecord.uLanguageID);

// highest priority
if (ttRecord.uPlatformID = PLATFORM_ID_MICROSOFT) then begin
// system language
if (ttRecord.uLanguageID = languageID) then begin
if Prio <= 7 then begin
ExtractName;

Prio := 7;
end;
end else

// english
if (ttRecord.uLanguageID = 1033) then begin
if Prio <= 6 then begin
ExtractName;

Prio := 6;
end;
end else

// all else
if Prio <= 5 then begin
ExtractName;

Prio := 5;
end;
end else

// apple unicode
if (ttRecord.uPlatformID = PLATFORM_ID_APPLE_UNICODE) then begin
ExtractName;

Prio := 4;
end else

// macintosh
if (ttRecord.uPlatformID = PLATFORM_ID_MACINTOSH) then begin
// english
if (ttRecord.uLanguageID = 0) then begin
if Prio <= 3 then begin
ExtractName;

Prio := 3;
end;
end else

// all other
begin
ExtractName;

Prio := 2;
end;
end else

begin
if Prio <= 1 then begin
ExtractName;

Prio := 1;
end;
end;
end;
end;
end;

function GetTTFontFullNameFromStream(Stream: TStream; LanguageID: Cardinal): AnsiString;
var
TableName: Cardinal;
Buffer: Pointer;
BufferSize: Integer;
begin
TableName := MakeTTTableName('n', 'a', 'm', 'e');

if GetTTTableData(Stream, TableName, nil, BufferSize) then begin
GetMem(Buffer, BufferSize);
try
if GetTTTableData(Stream, TableName, Buffer, BufferSize) then begin
if not GetTTString(Buffer, BufferSize, NAME_ID_FULL_NAME, LanguageID, Result) then
if not GetTTString(Buffer, BufferSize, NAME_ID_FACE_NAME, LanguageID, Result) then
Result := '';
end;
finally
FreeMem(Buffer);
end;
end;
end;

function GetTTFontFullNameFromFile(Filename: AnsiString; LanguageID: Cardinal): AnsiString;
var
fs: TFileStream;
begin
fs := TFileStream.Create(String(Filename), fmOpenRead or fmShareDenyWrite);
try
result := GetTTFontFullNameFromStream(fs, LanguageID);
finally
fs.Free;
end;
end;

end.

+ 0
- 13
old/TextSuiteVersion.pas Просмотреть файл

@@ -1,13 +0,0 @@
unit TextSuiteVersion;

interface

const
TS_MAYOR_VERSION = 0;
TS_MINOR_VERSION = 8;
TS_BUILD_NUMBER = 1;
TS_VERSION_STR = '0.8.1';
implementation

end.

+ 0
- 1393
old/TextSuiteWideUtils.pas
Разница между файлами не показана из-за своего большого размера
Просмотреть файл


+ 79
- 41
utsFontCreatorFreeType.pas Просмотреть файл

@@ -35,6 +35,8 @@ type

function ConvertFont(const aFont: TtsFont): TtsFontFreeType;
procedure LoadNames(const aFace: FT_Face; var aProperties: TtsFontProperties);
function CreateFont(const aFace: FT_Face; const aRenderer: TtsRenderer; const aSize: Integer;
const aStyle: TtsFontStyles; const aAntiAliasing: TtsAntiAliasing): TtsFont;
protected
function GetGlyphMetrics(const aFont: TtsFont; const aCharCode: WideChar;
out aGlyphOrigin, aGlyphSize: TtsPosition; out aAdvance: Integer): Boolean; override;
@@ -43,6 +45,8 @@ type
public
function GetFontByFile(const aFilename: String; const aRenderer: TtsRenderer; const aSize: Integer;
const aStyle: TtsFontStyles; const aAntiAliasing: TtsAntiAliasing): TtsFont; overload;
function GetFontByStream(const aStream: TStream; const aRenderer: TtsRenderer; const aSize: Integer;
const aStyle: TtsFontStyles; const aAntiAliasing: TtsAntiAliasing): TtsFont; overload;

constructor Create(const aContext: TtsContext);
destructor Destroy; override;
@@ -170,6 +174,57 @@ begin
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TtsFontGeneratorFreeType.CreateFont(const aFace: FT_Face; const aRenderer: TtsRenderer; const aSize: Integer;
const aStyle: TtsFontStyles; const aAntiAliasing: TtsAntiAliasing): TtsFont;
var
face: FT_Face;
err: FT_Error;
prop: TtsFontProperties;
os2: PTT_OS2;
hz: PTT_HoriHeader;
begin
err := FT_Set_Char_Size(aFace, 0, aSize * FT_SIZE_FACTOR, FT_SIZE_RES, FT_SIZE_RES);
if (err <> 0) then
raise EtsException.Create('unable to set char size: error=' + IntToStr(err));

FillByte(prop{%H-}, SizeOf(prop), 0);
prop.AntiAliasing := tsAANormal;
prop.FaceName := aFace^.family_name;
prop.StyleName := aFace^.style_name;
LoadNames(aFace, prop);

prop.Size := aSize;
prop.AntiAliasing := aAntiAliasing;
prop.DefaultChar := '?';
prop.Style := aStyle + [tsStyleBold, tsStyleItalic];
if ((aFace^.style_flags and FT_STYLE_FLAG_BOLD) = 0) then
Exclude(prop.Style, tsStyleBold);
if ((aFace^.style_flags and FT_STYLE_FLAG_ITALIC) = 0) then
Exclude(prop.Style, tsStyleItalic);

prop.Ascent := aFace^.size^.metrics.ascender div FT_SIZE_FACTOR;
prop.Descent := -aFace^.size^.metrics.descender div FT_SIZE_FACTOR;
prop.ExternalLeading := 0;
prop.BaseLineOffset := 0;

prop.UnderlinePos := aFace^.underline_position div FT_SIZE_FACTOR;
prop.UnderlineSize := aFace^.underline_thickness div FT_SIZE_FACTOR;

os2 := PTT_OS2(FT_Get_Sfnt_Table(aFace, FT_SFNT_OS2));
if Assigned(os2) and (os2^.version <> $FFFF) then begin
prop.StrikeoutPos := os2^.yStrikeoutPosition div FT_SIZE_FACTOR;
prop.StrikeoutSize := os2^.yStrikeoutSize div FT_SIZE_FACTOR;
end;

hz := PTT_HoriHeader(FT_Get_Sfnt_Table(aFace, FT_SFNT_HHEA));
if Assigned(hz) then begin
prop.ExternalLeading := hz^.Line_Gap div FT_SIZE_FACTOR;
end;

result := TtsFontFreeType.Create(TtsFreeTypeFaceHandle.Create(aFace), aRenderer, self, prop);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TtsFontGeneratorFreeType.GetGlyphMetrics(const aFont: TtsFont; const aCharCode: WideChar; out aGlyphOrigin, aGlyphSize: TtsPosition; out aAdvance: Integer): Boolean;
var
@@ -303,53 +358,36 @@ function TtsFontGeneratorFreeType.GetFontByFile(const aFilename: String; const a
var
face: FT_Face;
err: FT_Error;
prop: TtsFontProperties;
os2: PTT_OS2;
hz: PTT_HoriHeader;
begin
err := FT_New_Face(fHandle, PAnsiChar(aFilename), 0, @face);
if (err <> 0) then
raise EtsException.Create('unable to create free type face from file: ' + aFilename + ' error=' + IntToStr(err));
result := CreateFont(face, aRenderer, aSize, aStyle, aAntiAliasing);
end;

err := FT_Set_Char_Size(face, 0, aSize * FT_SIZE_FACTOR, FT_SIZE_RES, FT_SIZE_RES);
if (err <> 0) then
raise EtsException.Create('unable to set char size: error=' + IntToStr(err));

FillByte(prop{%H-}, SizeOf(prop), 0);
prop.AntiAliasing := tsAANormal;
prop.FaceName := face^.family_name;
prop.StyleName := face^.style_name;
LoadNames(face, prop);

prop.Size := aSize;
prop.AntiAliasing := aAntiAliasing;
prop.DefaultChar := '?';
prop.Style := aStyle + [tsStyleBold, tsStyleItalic];
if ((face^.style_flags and FT_STYLE_FLAG_BOLD) = 0) then
Exclude(prop.Style, tsStyleBold);
if ((face^.style_flags and FT_STYLE_FLAG_ITALIC) = 0) then
Exclude(prop.Style, tsStyleItalic);

prop.Ascent := face^.size^.metrics.ascender div FT_SIZE_FACTOR;
prop.Descent := -face^.size^.metrics.descender div FT_SIZE_FACTOR;
prop.ExternalLeading := 0;
prop.BaseLineOffset := 0;

prop.UnderlinePos := face^.underline_position div FT_SIZE_FACTOR;
prop.UnderlineSize := face^.underline_thickness div FT_SIZE_FACTOR;

os2 := PTT_OS2(FT_Get_Sfnt_Table(face, FT_SFNT_OS2));
if Assigned(os2) and (os2^.version <> $FFFF) then begin
prop.StrikeoutPos := os2^.yStrikeoutPosition div FT_SIZE_FACTOR;
prop.StrikeoutSize := os2^.yStrikeoutSize div FT_SIZE_FACTOR;
end;

hz := PTT_HoriHeader(FT_Get_Sfnt_Table(face, FT_SFNT_HHEA));
if Assigned(hz) then begin
prop.ExternalLeading := hz^.Line_Gap div FT_SIZE_FACTOR;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TtsFontGeneratorFreeType.GetFontByStream(const aStream: TStream; const aRenderer: TtsRenderer;
const aSize: Integer; const aStyle: TtsFontStyles; const aAntiAliasing: TtsAntiAliasing): TtsFont;
var
face: FT_Face;
err: FT_Error;
ms: TMemoryStream;
begin
if (aStream is TMemoryStream) then begin
ms := (aStream as TMemoryStream);
err := FT_New_Memory_Face(fHandle, PByte(ms.Memory) + ms.Position, ms.Size - ms.Position, 0, @face);
end else begin
ms := TMemoryStream.Create;
try
ms.CopyFrom(aStream, aStream.Size - aStream.Position);
err := FT_New_Memory_Face(fHandle, PByte(ms.Memory), ms.Size, 0, @face);
finally
FreeAndNil(ms);
end;
end;

result := TtsFontFreeType.Create(TtsFreeTypeFaceHandle.Create(face), aRenderer, self, prop);
if (err <> 0) then
raise EtsException.Create('unable to create free type face from stream: error=' + IntToStr(err));
result := CreateFont(face, aRenderer, aSize, aStyle, aAntiAliasing);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


+ 3
- 3
utsFontCreatorGDI.pas Просмотреть файл

@@ -505,11 +505,11 @@ begin
Size := GetGlyphOutlineA(DC, GlyphIndex, GGO_METRICS or GGO_GLYPH_INDEX, @Metric, 0, nil, @font.fMat2);

if (Size <> GDI_ERROR) then begin
aGlyphOrigin.x := Round(Metric.gmptGlyphOrigin.x / font.fMat2.eM11.value);
aGlyphOrigin.x := Metric.gmptGlyphOrigin.x;
aGlyphOrigin.y := Metric.gmptGlyphOrigin.y;
aGlyphSize.x := Round(Metric.gmBlackBoxX / font.fMat2.eM11.value);
aGlyphSize.x := Metric.gmBlackBoxX;
aGlyphSize.y := Metric.gmBlackBoxY;
aAdvance := Round(Metric.gmCellIncX / font.fMat2.eM11.value);
aAdvance := Metric.gmCellIncX;
result := true;
end;
finally


+ 27
- 14
utsFreeType.pas Просмотреть файл

@@ -326,10 +326,11 @@ type
short_metrics: Pointer;
end;

TFT_Init_FreeType = function(aLibrary: PFT_Library): FT_Error;
TFT_Done_FreeType = function(aLibrary: FT_Library): FT_Error;
TFT_New_Face = function(aLibrary: FT_Library; const aFilename: PAnsiChar; aFaceIndex: FT_Long; aFace: PFT_Face): FT_Error;
TFT_Done_Face = function(aFace: FT_Face): FT_Error;
TFT_Init_FreeType = function(aLibrary: PFT_Library): FT_Error;
TFT_Done_FreeType = function(aLibrary: FT_Library): FT_Error;
TFT_New_Face = function(aLibrary: FT_Library; const aFilename: PAnsiChar; aFaceIndex: FT_Long; aFace: PFT_Face): FT_Error;
TFT_New_Memory_Face = function(aLibrary: FT_Library; aData: PByte; aSize: FT_Long; aFaceIndex: FT_Long; aFace: PFT_Face): FT_Error;
TFT_Done_Face = function(aFace: FT_Face): FT_Error;

TFT_Get_Sfnt_Name_Count = function(aFace: FT_Face): FT_UInt;
TFT_Get_Sfnt_Name = function(aFace: FT_Face; aIndex: FT_UInt; aName: PFT_SfntName): FT_Error;
@@ -339,10 +340,11 @@ type
TFT_Get_Sfnt_Table = function(aFace: FT_Face; aTag: Integer): Pointer;

var
FT_Init_FreeType: TFT_Init_FreeType;
FT_Done_FreeType: TFT_Done_FreeType;
FT_New_Face: TFT_New_Face;
FT_Done_Face: TFT_Done_Face;
FT_Init_FreeType: TFT_Init_FreeType;
FT_Done_FreeType: TFT_Done_FreeType;
FT_New_Face: TFT_New_Face;
FT_New_Memory_Face: TFT_New_Memory_Face;
FT_Done_Face: TFT_Done_Face;

FT_Get_Sfnt_Name_Count: TFT_Get_Sfnt_Name_Count;
FT_Get_Sfnt_Name: TFT_Get_Sfnt_Name;
@@ -648,10 +650,11 @@ begin
raise EtsException.Create('unable to load free type lib: ' + LIB_FREE_TYPE + ' error=' + IntToStr(GetLastOSError));
end;

FT_Init_FreeType := TFT_Init_FreeType(GetProcAddr('FT_Init_FreeType'));
FT_Done_FreeType := TFT_Done_FreeType(GetProcAddr('FT_Done_FreeType'));
FT_New_Face := TFT_New_Face( GetProcAddr('FT_New_Face'));
FT_Done_Face := TFT_Done_Face( GetProcAddr('FT_Done_Face'));
FT_Init_FreeType := TFT_Init_FreeType( GetProcAddr('FT_Init_FreeType'));
FT_Done_FreeType := TFT_Done_FreeType( GetProcAddr('FT_Done_FreeType'));
FT_New_Face := TFT_New_Face( GetProcAddr('FT_New_Face'));
FT_New_Memory_Face := TFT_New_Memory_Face(GetProcAddr('FT_New_Memory_Face'));
FT_Done_Face := TFT_Done_Face( GetProcAddr('FT_Done_Face'));

FT_Get_Sfnt_Name_Count := TFT_Get_Sfnt_Name_Count(GetProcAddr('FT_Get_Sfnt_Name_Count'));
FT_Get_Sfnt_Name := TFT_Get_Sfnt_Name( GetProcAddr('FT_Get_Sfnt_Name'));
@@ -684,8 +687,18 @@ begin

FT_Done_FreeType(ftLibrary);

FT_Init_FreeType := nil;
FT_Done_FreeType := nil;
FT_Init_FreeType := nil;
FT_Done_FreeType := nil;
FT_New_Face := nil;
FT_New_Memory_Face := nil;
FT_Done_Face := nil;

FT_Get_Sfnt_Name_Count := nil;
FT_Get_Sfnt_Name := nil;

FT_Set_Char_Size := nil;
FT_Load_Char := nil;
FT_Get_Sfnt_Table := nil;

if (FreeTypeLibHandle <> 0) then begin
FreeLibrary(FreeTypeLibHandle);


+ 11
- 7
utsOpenGLUtils.pas Просмотреть файл

@@ -199,7 +199,7 @@ var

function AddToTexture(const aTexture: PtsFontTexture): TtsCharRenderRefOpenGL;
var
x, y: Integer;
x, y, wChar, hChar, l, t: Integer;
item: PtsTextureTreeItem;
begin
item := InsertToTree(aTexture^.Usage, 0, 0, aTexture^.Size, aTexture^.Size, x, y);
@@ -209,18 +209,22 @@ var
item^.ref := TtsCharRenderRefOpenGL.Create;
result := item^.ref;

wChar := aChar.GlyphRect.Right - aChar.GlyphRect.Left;
hChar := aChar.GlyphRect.Bottom - aChar.GlyphRect.Top;
l := aChar.GlyphRect.Left + x;
t := aChar.GlyphRect.Top + y;
result.TextureID := aTexture^.ID;
result.Size := tsPosition(aCharImage.Width, aCharImage.Height);
result.TexMat := tsMatrix4f(
tsVector4f(aCharImage.Width / aTexture^.Size, 0.0, 0.0, 0.0),
tsVector4f(0.0, aCharImage.Height / aTexture^.Size, 0.0, 0.0),
tsVector4f(wChar / aTexture^.Size, 0.0, 0.0, 0.0),
tsVector4f(0.0, hChar / aTexture^.Size, 0.0, 0.0),
tsVector4f(0.0, 0.0, 1.0, 0.0),
tsVector4f(x / aTexture^.Size, y / aTexture^.Size, 0.0, 1.0));
tsVector4f(l / aTexture^.Size, t / aTexture^.Size, 0.0, 1.0));
result.VertMat := tsMatrix4f(
tsVector4f(aCharImage.Width, 0.0, 0.0, 0.0),
tsVector4f(0.0, aCharImage.Height, 0.0, 0.0),
tsVector4f(wChar, 0.0, 0.0, 0.0),
tsVector4f(0.0, hChar, 0.0, 0.0),
tsVector4f(0.0, 0.0, 1.0, 0.0),
tsVector4f(-aChar.GlyphRect.Left, -aChar.GlyphRect.Top - aChar.GlyphOrigin.y, 0.0, 1.0));
tsVector4f(aChar.GlyphOrigin.x, -aChar.GlyphOrigin.y, 0.0, 1.0));

UploadTexData(result, aCharImage, x, y);
end;


+ 26
- 17
utsPostProcess.pas Просмотреть файл

@@ -42,12 +42,12 @@ type
private
fKernel: TtsKernel2D;
fColor: TtsColor4f;
fUpdateCharSize: Boolean;
fKeepCharSize: Boolean;
public
procedure Execute(const aChar: TtsChar; const aCharImage: TtsImage); override;
public
constructor Create(const aWidth, aStrength: Single; const aColor: TtsColor4f;
const aUpdateCharSize: Boolean = false);
const aKeepCharSize: Boolean = false);
destructor Destroy; override;
end;

@@ -184,27 +184,31 @@ begin
FreeAndNil(orig);
end;

if fUpdateCharSize then begin
aChar.GlyphRect := tsRect(
aChar.GlyphRect.Left + fKernel.SizeX - fKernel.MidSizeX,
aChar.GlyphRect.Top + fKernel.SizeY - fKernel.MidSizeY,
aChar.GlyphRect.Right + fKernel.SizeX + fKernel.MidSizeX,
aChar.GlyphRect.Bottom + fKernel.SizeY + fKernel.MidSizeY);
aChar.GlyphRect := tsRect(
aChar.GlyphRect.Left,
aChar.GlyphRect.Top,
aChar.GlyphRect.Right + 2 * fKernel.SizeX,
aChar.GlyphRect.Bottom + 2 * fKernel.SizeY);

if fKeepCharSize then begin
aChar.GlyphOrigin := tsPosition(
aChar.GlyphOrigin.x + fKernel.MidSizeX,
aChar.GlyphOrigin.y + fKernel.MidSizeY);
aChar.Advance := aChar.Advance + fKernel.MidSizeX ;
aChar.GlyphOrigin.x - fKernel.SizeX,
aChar.GlyphOrigin.y + fKernel.SizeY);
end else begin
aChar.Advance := aChar.Advance + 2 * fKernel.SizeX;
aChar.GlyphOrigin := tsPosition(
aChar.GlyphOrigin.x,
aChar.GlyphOrigin.y + fKernel.SizeY);
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TtsPostProcessBorder.Create(const aWidth, aStrength: Single; const aColor: TtsColor4f;
const aUpdateCharSize: Boolean);
constructor TtsPostProcessBorder.Create(const aWidth, aStrength: Single; const aColor: TtsColor4f; const aKeepCharSize: Boolean);
begin
inherited Create;
fKernel := TtsKernel2D.Create(aWidth, aStrength);
fColor := aColor;
fUpdateCharSize := aUpdateCharSize;
fKernel := TtsKernel2D.Create(aWidth, aStrength);
fColor := aColor;
fKeepCharSize := aKeepCharSize;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -236,9 +240,14 @@ begin
tmpY := fKernel.Size - fY;
aCharImage.Blend(orig, tmpX, tmpY, @tsBlendFundAlpha);

aChar.GlyphRect := tsRect(
aChar.GlyphRect.Left,
aChar.GlyphRect.Top,
aChar.GlyphRect.Right + 2 * fKernel.Size,
aChar.GlyphRect.Bottom + 2 * fKernel.Size);
aChar.GlyphOrigin := tsPosition(
aChar.GlyphOrigin.x - tmpX,
aChar.GlyphOrigin.y - tmpX);
aChar.GlyphOrigin.y + tmpX);
finally
FreeAndNil(orig);
end;


+ 9
- 3
utsRendererOpenGL.pas Просмотреть файл

@@ -25,7 +25,7 @@ type
procedure SetDrawPos(const X, Y: Integer); override;
procedure MoveDrawPos(const X, Y: Integer); override;
procedure SetColor(const aColor: TtsColor4f); override;
procedure Render(const aCharRef: TtsCharRenderRef); override;
procedure Render(const aCharRef: TtsCharRenderRef; const aForcedWidth: Integer); override;
public
constructor Create(const aContext: TtsContext; const aFormat: TtsFormat);
destructor Destroy; override;
@@ -171,9 +171,10 @@ begin
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TtsRendererOpenGL.Render(const aCharRef: TtsCharRenderRef);
procedure TtsRendererOpenGL.Render(const aCharRef: TtsCharRenderRef; const aForcedWidth: Integer);
var
ref: TtsCharRenderRefOpenGL;
m: TtsMatrix4f;
begin
if Assigned(aCharRef) and (aCharRef is TtsCharRenderRefOpenGL) then begin
ref := (aCharRef as TtsCharRenderRefOpenGL);
@@ -188,7 +189,12 @@ begin

glMatrixMode(GL_MODELVIEW);
glPushMatrix;
glMultMatrixf(@ref.VertMat[0, 0]);
if (aForcedWidth > 0) then begin
m := ref.VertMat;
m[0] := tsVector4f(aForcedWidth, 0, 0, 0);
glMultMatrixf(@m[0, 0]);
end else
glMultMatrixf(@ref.VertMat[0, 0]);

glBindBuffer(GL_ARRAY_BUFFER, fVBO);
glEnableClientState(GL_VERTEX_ARRAY);


+ 11
- 4
utsRendererOpenGLES.pas Просмотреть файл

@@ -42,7 +42,7 @@ type
procedure SetDrawPos(const X, Y: Integer); override;
procedure MoveDrawPos(const X, Y: Integer); override;
procedure SetColor(const aColor: TtsColor4f); override;
procedure Render(const aCharRef: TtsCharRenderRef); override;
procedure Render(const aCharRef: TtsCharRenderRef; const aForcedWidth: Integer); override;
public
property ShaderProgram: GLuint read fShaderProgram write SetShaderProgram;
property ProjectionMatrix: TtsMatrix4f read fProjMatrix write SetProjectionMatrix;
@@ -354,9 +354,10 @@ begin
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TtsRendererOpenGLES.Render(const aCharRef: TtsCharRenderRef);
procedure TtsRendererOpenGLES.Render(const aCharRef: TtsCharRenderRef; const aForcedWidth: Integer);
var
ref: TtsCharRenderRefOpenGL;
m: TtsMatrix4f;
begin
if Assigned(aCharRef) and (aCharRef is TtsCharRenderRefOpenGL) then begin
ref := (aCharRef as TtsCharRenderRefOpenGL);
@@ -369,8 +370,14 @@ begin
glVertexAttribPointer(ATTRIB_LOCATION_TEXCOORD, 2, GL_FLOAT, false, SizeOf(TVertex), Pointer(8));
glUseProgram(fShaderProgram);

if (fCharPosLocation >= 0) then
glUniformMatrix4fv(fCharPosLocation, 1, false, @ref.VertMat);
if (fCharPosLocation >= 0) then begin
if (aForcedWidth > 0) then begin
m := ref.VertMat;
m[0] := tsVector4f(aForcedWidth, 0, 0, 0);
glUniformMatrix4fv(fCharPosLocation, 1, false, @m[0, 0]);
end else
glUniformMatrix4fv(fCharPosLocation, 1, false, @ref.VertMat[0, 0]);
end;
if (fCharTexPosLocation >= 0) then
glUniformMatrix4fv(fCharTexPosLocation, 1, false, @ref.TexMat);



+ 61
- 40
utsTextSuite.pas Просмотреть файл

@@ -384,7 +384,7 @@ type
function GetDrawPos: TtsPosition; virtual; abstract;
procedure MoveDrawPos(const X, Y: Integer); virtual; abstract;
procedure SetColor(const aColor: TtsColor4f); virtual; abstract;
procedure Render(const aCharRef: TtsCharRenderRef); virtual; abstract;
procedure Render(const aCharRef: TtsCharRenderRef; const aForcedWidth: Integer = 0); virtual; abstract;
public
property Context: TtsContext read fContext;
property Format: TtsFormat read fFormat;
@@ -1287,7 +1287,8 @@ end;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TtsFontGenerator.DrawLine(const aChar: TtsChar; const aCharImage: TtsImage; aLinePosition, aLineSize: Integer);
var
NewSize, NewPos: TtsPosition;
ImgSize, ImgPos, Origin: TtsPosition;
Rect: TtsRect;
YOffset, y: Integer;

procedure FillLine(aData: PByte);
@@ -1296,7 +1297,7 @@ var
c: TtsColor4f;
tmp: PByte;
begin
w := NewSize.x;
w := aCharImage.Width;
while (w > 0) do begin
tmp := aData;
tsFormatUnmap(aCharImage.Format, tmp, c);
@@ -1314,47 +1315,56 @@ begin
aLinePosition := aLinePosition - aLineSize;

// calculate width and height
NewPos.x := 0;
NewPos.y := 0;
NewSize.x := aCharImage.Width;
NewSize.y := aCharImage.Height;
ImgPos := tsPosition(0, 0);
ImgSize := tsPosition(aCharImage.Width, aCharImage.Height);
Origin := aChar.GlyphOrigin;
Rect := aChar.GlyphRect;

// expand image to the full advance
if aChar.Advance > aCharImage.Width then
NewSize.x := aChar.Advance;
// expand left rect border to origin
if (Origin.x > 0) then begin
dec(Rect.Left, Origin.x);
Origin.x := 0;
end;

// add glyph position to image width and set position
if aChar.GlyphOrigin.x > aChar.GlyphRect.Left then begin
NewSize.x := NewSize.x + aChar.GlyphOrigin.x;
NewPos.x := aChar.GlyphOrigin.x;
// expand right rect border to advanced
if (Rect.Right - Rect.Left < aChar.Advance) then begin
Rect.Right := Rect.Left + aChar.Advance;
end;
if (aChar.GlyphOrigin.x < 0) then
NewSize.x := NewSize.x - aChar.GlyphOrigin.x;

// line is under the image
if aLinePosition < (aChar.GlyphOrigin.y - aCharImage.Height) then
NewSize.y := NewSize.y + (aChar.GlyphOrigin.y - aCharImage.Height - aLinePosition);
// expand bottom rect border
if (Origin.y - aLinePosition > Rect.Bottom) then begin
Rect.Bottom := Origin.y - aLinePosition;
end;

// line is above the image
if aLinePosition + aLineSize > aChar.GlyphOrigin.y then begin
NewPos.y := ((aLinePosition + aLineSize) - aChar.GlyphOrigin.y);
NewSize.y := NewSize.y + NewPos.y;
// expand top rect border
if (Origin.y - aLinePosition - aLineSize < Rect.Top) then begin
Rect.Top := Origin.y - aLinePosition - aLineSize;
Origin.y := aLinePosition + aLineSize;
end;

// resize
aCharImage.Resize(NewSize.x, NewSize.y, NewPos.x, NewPos.y);
// update image size
if (Rect.Right - Rect.Left > ImgSize.x) then begin
ImgSize.x := Rect.Right - Rect.Left;
ImgPos.x := Max(-Rect.Left, 0);
inc(Rect.Left, ImgPos.x);
inc(Rect.Right, ImgPos.x);
end;
if (Rect.Bottom - Rect.Top > ImgSize.y) then begin
ImgSize.y := Rect.Bottom - Rect.Top;
ImgPos.y := Max(-Rect.Top, 0);
inc(Rect.Top, ImgPos.y);
inc(Rect.Bottom, ImgPos.y);
end;
aCharImage.Resize(ImgSize.x, ImgSize.y, ImgPos.x, ImgPos.y);

// draw lines
YOffset := (aChar.GlyphOrigin.y + NewPos.y) - aLinePosition;
YOffset := Rect.Top + Origin.y - aLinePosition;
for y := 1 to aLineSize do
FillLine(aCharImage.ScanLine[YOffset - y]);

// move glyph rect
aChar.GlyphRect := tsRect(
aChar.GlyphRect.Left + NewPos.x,
aChar.GlyphRect.Top + NewPos.y,
aChar.GlyphRect.Right + NewPos.x,
aChar.GlyphRect.Bottom + NewPos.y);
aChar.GlyphOrigin := Origin;
aChar.GlyphRect := Rect;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1393,14 +1403,19 @@ var
CharImage: TtsImage;
begin
result := nil;
if not GetGlyphMetrics(aFont, aCharCode, GlyphOrigin, GlyphSize, Advance) or
not ((GlyphOrigin.x <> 0) or (GlyphOrigin.y <> 0) or (GlyphSize.x <> 0) or (GlyphSize.y <> 0) or (Advance <> 0)) then
if (aCharCode <> #0) and
(not GetGlyphMetrics(aFont, aCharCode, GlyphOrigin, GlyphSize, Advance) or
not ((GlyphOrigin.x <> 0) or (GlyphOrigin.y <> 0) or (GlyphSize.x <> 0) or (GlyphSize.y <> 0) or (Advance <> 0))) then
exit;

CharImage := TtsImage.Create;
try
if aRenderer.SaveImages then begin
if (GlyphSize.x > 0) and (GlyphSize.y > 0) then
if (aCharCode = #0) then begin
CharImage.CreateEmpty(aRenderer.Format, 3, 1);
GlyphOrigin := tsPosition(0, 1);
Advance := 1;
end else if (GlyphSize.x > 0) and (GlyphSize.y > 0) then
GetCharImage(aFont, aCharCode, CharImage);

if CharImage.IsEmpty and ([tsStyleUnderline, tsStyleStrikeout] * aFont.Properties.Style <> []) then begin
@@ -1412,8 +1427,11 @@ begin
result := TtsChar.Create(aCharCode);
try
result.GlyphOrigin := GlyphOrigin;
result.GlyphRect := tsRect(0, 0, CharImage.Width, CharImage.Height);
result.Advance := Advance;
if (aCharCode = #0) then
result.GlyphRect := tsRect(1, 0, 2, 1)
else
result.GlyphRect := tsRect(0, 0, CharImage.Width, CharImage.Height);

if (aRenderer.SaveImages) then begin
try
@@ -2032,9 +2050,9 @@ var
while (c^ <> #0) do begin
char := GetChar(c^);
if Assigned(char) then begin
MoveDrawPos(Char.GlyphOrigin.x, -metric.BaseLineOffset);
MoveDrawPos(0, -metric.BaseLineOffset);
Render(char.RenderRef);
MoveDrawPos(char.Advance - char.GlyphOrigin.x + font.CharSpacing, metric.BaseLineOffset);
MoveDrawPos(char.Advance + font.CharSpacing, metric.BaseLineOffset);
end;
inc(c);
end;
@@ -2049,9 +2067,9 @@ var
char := GetChar(c^);
if Assigned(char) then begin
if (font.Properties.Style * [tsStyleUnderline, tsStyleStrikeout] <> []) then begin
MoveDrawPos(char.GlyphOrigin.x, -metric.BaseLineOffset);
MoveDrawPos(0, -metric.BaseLineOffset);
Render(char.RenderRef);
MoveDrawPos(char.Advance - char.GlyphOrigin.x + font.CharSpacing, metric.BaseLineOffset);
MoveDrawPos(char.Advance + font.CharSpacing, metric.BaseLineOffset);
end else begin
MoveDrawPos(char.Advance + font.CharSpacing, 0);
end;
@@ -2062,6 +2080,9 @@ var
tmp := Trunc(ExtraSpaceActual);
ExtraSpaceActual := ExtraSpaceActual - tmp;
if (font.Properties.Style * [tsStyleUnderline, tsStyleStrikeout] <> []) then begin
char := GetChar(#0);
if Assigned(char) then
Render(char.RenderRef, tmp);
// TODO draw lines; maybe with a temporary created fake char or something like an empty char?
end;
MoveDrawPos(tmp, 0);
@@ -2108,7 +2129,7 @@ var
tsHorzAlignRight:
x := rect.Right - line^.meta.Width;
tsHorzAlignJustify:
if (tsAutoLineBreak in line^.Flags) then
if (tsAutoLineBreak in line^.Flags) and (line^.meta.SpaceCount > 0) then
ExtraSpaceTotal := (aBlock.Width - line^.meta.Width) / line^.meta.SpaceCount;
end;



Загрузка…
Отмена
Сохранить