Browse Source

* improved examples

master
Bergmann89 7 years ago
parent
commit
87836c02e0
21 changed files with 21857 additions and 255 deletions
  1. +12
    -0
      header/examples/c/Makefile
  2. +15
    -5
      header/examples/c/example.c
  3. +8
    -3
      header/examples/c/helper.h
  4. +57
    -0
      header/examples/c/main-gnuc.c
  5. +1
    -1
      header/examples/c/main-mingw.c
  6. +12
    -0
      header/examples/cpp/Makefile
  7. +16
    -5
      header/examples/cpp/example.cpp
  8. +8
    -3
      header/examples/cpp/helper.h
  9. +74
    -0
      header/examples/cpp/main-gnuc.cpp
  10. +182
    -0
      header/examples/cpp/main-mingw.cpp
  11. +0
    -159
      header/examples/cpp/main.cpp
  12. +20638
    -0
      header/examples/fpc/dglOpenGL.pas
  13. +1
    -1
      header/examples/fpc/example.lpi
  14. +2
    -2
      header/examples/fpc/uMainForm.lfm
  15. +735
    -20
      header/examples/fpc/uMainForm.pas
  16. +30
    -19
      header/libTextSuite.h
  17. +54
    -31
      header/libTextSuite.hpp
  18. +5
    -3
      header/ulibTextSuite.pas
  19. +5
    -2
      libTextSuite.lpi
  20. +1
    -0
      libTextSuite.lpr
  21. +1
    -1
      src/TextSuite

+ 12
- 0
header/examples/c/Makefile View File

@@ -0,0 +1,12 @@
all:
$(info call one of the following rules to build for a specific compiler: mingw, gnuc)

mingw:
gcc -DWIN32 example.c main-mingw.c -lopengl32 -mwindows -o example.exe

gnuc:
gcc -DLINUX -o example main-gnuc.c example.c -lGL -lGLU -lglut -ldl

clean:
rm -rf example
rm -rf example.exe

+ 15
- 5
header/examples/c/example.c View File

@@ -3,7 +3,11 @@

#include "example.h"
#include "helper.h"
#include "..\..\libTextSuite.h"
#ifdef LINUX
# include "../../libTextSuite.h"
#else
# include "..\..\libTextSuite.h"
#endif

#if _WIN64
# define LIB_NAME "..\\..\\..\\libTextSuite-x86_64-win64.dll"
@@ -17,6 +21,12 @@
# error 'unknown operation system'
#endif

#ifdef LINUX
# define FontCreator ltsFontCreatorFreeType
#else
# define FontCreator ltsFontCreatorGDI
#endif

lts_context_handle_t context;
lts_font_creator_handle_t creator;
lts_renderer_handle_t renderer;
@@ -26,9 +36,9 @@ lts_post_processor_handle_t ppFillPattern;
lts_post_processor_handle_t ppFillColor;
lts_post_processor_handle_t ppBorder;

const char* 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.";
const wchar_t CHAR_RANGE_LOREM[] = { 'L', 'o', 'r', 'e', 'm', 0 };
const wchar_t CHAR_RANGE_E[] = { 'e', 0 };
const char* 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.";
const lts_wchar_t CHAR_RANGE_LOREM[] = { 'L', 'o', 'r', 'e', 'm', 0 };
const lts_wchar_t CHAR_RANGE_E[] = { 'e', 0 };

const uint8_t PATTER_DATA[] = {
0xFF, 0xBF, 0x7F, 0xBF,
@@ -66,7 +76,7 @@ bool exampleInit()
return false;
}
creator = lts_font_creator_create(context, ltsFontCreatorGDI);
creator = lts_font_creator_create(context, FontCreator);
if (!creator)
{
showMessage("unable to create text suite creator");


+ 8
- 3
header/examples/c/helper.h View File

@@ -1,11 +1,16 @@
#ifndef HELPER_H
#define HELPER_H

#if defined(WIN32)
#include <windows.h>

extern HWND hwnd;

inline void showMessage(const char* msg)
static inline void showMessage(const char* msg)
{ MessageBox(hwnd, msg, "TextSuiteExample Error", MB_OK); };
#elif defined(LINUX)
#include <stdio.h>
static inline void showMessage(const char* msg)
{ printf("%s\n", msg); };
#endif

#endif /* HELPER_H */

+ 57
- 0
header/examples/c/main-gnuc.c View File

@@ -0,0 +1,57 @@
#include <GL/gl.h>
#include <GL/glut.h>

#include "example.h"
#include "helper.h"

static int windowId;
static int screenw, screenh;

static void Resize(int width, int height)
{
screenw = width;
screenh = height;
glViewport(0, 0, screenw, screenh);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, screenw, screenh, 0, -10, 10);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

static void Render(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (!exampleRender(screenw, screenh))
{
glutDestroyWindow(windowId);
return;
}
glutSwapBuffers();
}

int main(int argc, char** argv)
{
glutInit(&argc, argv);

glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(640, 480);
windowId = glutCreateWindow("libTextSuite example");

glClearColor(1.0, 1.0, 1.0, 1.0);
if (!exampleInit())
return 1;
glutReshapeFunc(Resize);
glutDisplayFunc(Render);

glutMainLoop();
exampleFinish();
}

header/examples/c/main.c → header/examples/c/main-mingw.c View File

@@ -138,7 +138,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine
if ((hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"TextSuiteExample",
"libTextSuite example",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
NULL, NULL, hInstance, NULL)) == NULL)

+ 12
- 0
header/examples/cpp/Makefile View File

@@ -0,0 +1,12 @@
all:
$(info call one of the following rules to build for a specific compiler: mingw, gnuc)

mingw:
g++ -std=c++11 -DWIN32 -static-libgcc -static-libstdc++ main-mingw.cpp example.cpp -lopengl32 -mwindows -o example.exe

gnuc:
g++ -std=c++11 -DLINUX -o example main-gnuc.cpp example.cpp -lGL -lGLU -lglut -ldl

clean:
rm -rf example
rm -rf example.exe

+ 16
- 5
header/examples/cpp/example.cpp View File

@@ -1,9 +1,14 @@
#include <stdio.h>
#include <GL/gl.h>
#include <string.h>

#include "example.h"
#include "helper.h"
#include "..\..\libTextSuite.hpp"
#ifdef LINUX
# include "../../libTextSuite.hpp"
#else
# include "..\..\libTextSuite.hpp"
#endif

#if _WIN64
static const std::string LibName("..\\..\\..\\libTextSuite-x86_64-win64.dll");
@@ -17,6 +22,12 @@
# error 'unknown operation system'
#endif

#ifdef LINUX
# define FontCreatorExample FontCreatorFreeType
#else
# define FontCreatorExample FontCreatorGDI
#endif

typedef std::unique_ptr<lts::PostProcessor> PostProcessorPtrU;

std::shared_ptr<lts::Library> library;
@@ -28,9 +39,9 @@ std::shared_ptr<lts::Font> font;

std::shared_ptr<lts::PostProcessorList<PostProcessorPtrU>> ppList;

const char* 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.";
const wchar_t CHAR_RANGE_LOREM[] = { 'L', 'o', 'r', 'e', 'm', 0 };
const wchar_t CHAR_RANGE_E[] = { 'e', 0 };
const char* 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.";
const lts::WideChar CHAR_RANGE_LOREM[] = { 'L', 'o', 'r', 'e', 'm', 0 };
const lts::WideChar CHAR_RANGE_E[] = { 'e', 0 };

const uint8_t PATTER_DATA[] = {
0xFF, 0xBF, 0x7F, 0xBF,
@@ -43,7 +54,7 @@ bool exampleInit()
{
library.reset(new lts::Library(LibName));
context.reset(new lts::Context(*library));
creator.reset(new lts::FontCreatorGDI(*context));
creator.reset(new lts::FontCreatorExample(*context));
renderer.reset(new lts::RendererOpenGL(*context, lts::Format::RGBA8));
ppList.reset(new lts::PostProcessorList<PostProcessorPtrU>(*context));


+ 8
- 3
header/examples/cpp/helper.h View File

@@ -1,11 +1,16 @@
#ifndef HELPER_H
#define HELPER_H

#if defined(WIN32)
#include <windows.h>

extern HWND hwnd;

inline void showMessage(const char* msg)
static inline void showMessage(const char* msg)
{ MessageBox(hwnd, msg, "TextSuiteExample Error", MB_OK); };
#elif defined(LINUX)
#include <stdio.h>
static inline void showMessage(const char* msg)
{ printf("%s\n", msg); };
#endif

#endif /* HELPER_H */

+ 74
- 0
header/examples/cpp/main-gnuc.cpp View File

@@ -0,0 +1,74 @@
#include <iostream>
#include <GL/gl.h>
#include <GL/glut.h>
#include <exception>

#include "example.h"
#include "helper.h"

static int windowId;
static int screenw, screenh;

static void Resize(int width, int height)
{
screenw = width;
screenh = height;
glViewport(0, 0, screenw, screenh);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, screenw, screenh, 0, -10, 10);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
}

static void Render(void)
{
try
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
if (!exampleRender(screenw, screenh))
{
glutDestroyWindow(windowId);
return;
}
glutSwapBuffers();
}
catch(const std::exception& ex)
{
std::cout << "Exception: " << ex.what() << std::endl;
glutDestroyWindow(windowId);
}
}

int main(int argc, char** argv)
{
try
{
glutInit(&argc, argv);

glutInitDisplayMode(GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE);
glutInitWindowSize(640, 480);
windowId = glutCreateWindow("libTextSuite example");

glClearColor(1.0, 1.0, 1.0, 1.0);
if (!exampleInit())
return 1;
glutReshapeFunc(Resize);
glutDisplayFunc(Render);

glutMainLoop();
exampleFinish();
}
catch(const std::exception& ex)
{
std::cout << "Exception: " << ex.what() << std::endl;
}
}

+ 182
- 0
header/examples/cpp/main-mingw.cpp View File

@@ -0,0 +1,182 @@
#include <iostream>
#include <exception>
#include <windows.h>
#include <Wingdi.h>
#include <GL/gl.h>
#include <stdio.h>

#include "helper.h"
#include "example.h"

const char g_szClassName[] = "OpenGLWindowClass";

HDC hdc;
HGLRC hglrc;
HWND hwnd;
int done = 0;
bool canRender = false;

int screenw, screenh;

void SysShutdown (void)
{
done = 1;
exampleFinish();
wglMakeCurrent(hdc, NULL);
wglDeleteContext(hglrc);
PostQuitMessage(0);
}

void setPixelFormat()
{
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
32,
0,0,0,0,0,0,0,0,0,0,0,0,0, // useles parameters
16,
0,0,0,0,0,0,0
};
int indexPixelFormat = ChoosePixelFormat(hdc, &pfd);
SetPixelFormat(hdc, indexPixelFormat, &pfd);
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
try
{
switch(msg)
{
case WM_CREATE:
if ((hdc = GetDC(hwnd)) == NULL) // get device context
{
MessageBox(hwnd, "Failed to Get the Window Device Context", "Device Context Error", MB_OK);
SysShutdown();
break;
}
setPixelFormat();
if ((hglrc = wglCreateContext(hdc)) == NULL)
{
MessageBox(hwnd, "Failed to Create the OpenGL Rendering Context", "OpenGL Rendering Context Error", MB_OK);
SysShutdown();
break;
}
if (!wglMakeCurrent(hdc, hglrc))
{
MessageBox(hwnd, "Failed to make OpenGL Rendering Context current", "OpenGL Rendering Context Error", MB_OK);
SysShutdown();
break;
}
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
if (!exampleInit())
{
SysShutdown();
break;
}
canRender = true;
break;
case WM_SIZE:
screenw = LOWORD(lParam);
screenh = HIWORD(lParam);
break;
case WM_PAINT:
if (!canRender)
break;
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, screenw, screenh);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, screenw, screenh, 0, -10, 10);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
if (!exampleRender(screenw, screenh))
SysShutdown();
SwapBuffers(hdc);
break;
case WM_CLOSE:
SysShutdown();
DestroyWindow(hwnd);
break;
case WM_DESTROY:
SysShutdown();
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}
catch(const std::exception& ex)
{
MessageBox(hwnd, ex.what(), "Exception", MB_OK);
SysShutdown();
}
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
try
{
WNDCLASSEX wc;
MSG Msg;

wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}

if ((hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"libTextSuite example",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
NULL, NULL, hInstance, NULL)) == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&Msg, NULL, 0, 0) > 0 && done == 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}
catch(const std::exception& ex)
{
std::cout << "Exception: " << ex.what() << std::endl;
}
}

+ 0
- 159
header/examples/cpp/main.cpp View File

@@ -1,159 +0,0 @@
#include <windows.h>
#include <Wingdi.h>
#include <GL/gl.h>

#include "example.h"

const char g_szClassName[] = "OpenGLWindowClass";

HDC hdc;
HGLRC hglrc;
HWND hwnd;
int done = 0;

int screenw, screenh;

void SysShutdown (void)
{
done = 1;
exampleFinish();
wglMakeCurrent(hdc, NULL);
wglDeleteContext(hglrc);
PostQuitMessage(0);
}

void setPixelFormat()
{
PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
32,
0,0,0,0,0,0,0,0,0,0,0,0,0, // useles parameters
16,
0,0,0,0,0,0,0
};
int indexPixelFormat = ChoosePixelFormat(hdc, &pfd);
SetPixelFormat(hdc, indexPixelFormat, &pfd);
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
switch(msg)
{
case WM_CREATE:
if ((hdc = GetDC(hwnd)) == NULL) // get device context
{
MessageBox(hwnd, "Failed to Get the Window Device Context", "Device Context Error", MB_OK);
SysShutdown();
break;
}
setPixelFormat();
if ((hglrc = wglCreateContext(hdc)) == NULL)
{
MessageBox(hwnd, "Failed to Create the OpenGL Rendering Context", "OpenGL Rendering Context Error", MB_OK);
SysShutdown();
break;
}
if (!wglMakeCurrent(hdc, hglrc))
{
MessageBox(hwnd, "Failed to make OpenGL Rendering Context current", "OpenGL Rendering Context Error", MB_OK);
SysShutdown();
break;
}
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
if (!exampleInit())
{
SysShutdown();
break;
}
break;
case WM_SIZE:
screenw = LOWORD(lParam);
screenh = HIWORD(lParam);
break;
case WM_PAINT:
glClearColor(1.0, 1.0, 1.0, 1.0);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, screenw, screenh);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, screenw, screenh, 0, -10, 10);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
if (!exampleRender(screenw, screenh))
SysShutdown();
SwapBuffers(hdc);
break;
case WM_CLOSE:
SysShutdown();
DestroyWindow(hwnd);
break;
case WM_DESTROY:
SysShutdown();
PostQuitMessage(0);
break;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
return 0;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wc;
MSG Msg;

wc.cbSize = sizeof(WNDCLASSEX);
wc.style = 0;
wc.lpfnWndProc = WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName = NULL;
wc.lpszClassName = g_szClassName;
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);

if(!RegisterClassEx(&wc))
{
MessageBox(NULL, "Window Registration Failed!", "Error!",
MB_ICONEXCLAMATION | MB_OK);
return 0;
}

if ((hwnd = CreateWindowEx(
WS_EX_CLIENTEDGE,
g_szClassName,
"TextSuiteExample",
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 640, 480,
NULL, NULL, hInstance, NULL)) == NULL)
{
MessageBox(NULL, "Window Creation Failed!", "Error!", MB_ICONEXCLAMATION | MB_OK);
return 0;
}
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
while(GetMessage(&Msg, NULL, 0, 0) > 0 && done == 0)
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
return Msg.wParam;
}

+ 20638
- 0
header/examples/fpc/dglOpenGL.pas
File diff suppressed because it is too large
View File


+ 1
- 1
header/examples/fpc/example.lpi View File

@@ -55,7 +55,7 @@
</Target>
<SearchPaths>
<IncludeFiles Value="$(ProjOutDir)"/>
<OtherUnitFiles Value="..\..\..\src\OpenGLCore;..\.."/>
<OtherUnitFiles Value="..\.."/>
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
</SearchPaths>
<Linking>


+ 2
- 2
header/examples/fpc/uMainForm.lfm View File

@@ -1,7 +1,7 @@
object MainForm: TMainForm
Left = 876
Left = 1121
Height = 500
Top = 270
Top = 232
Width = 640
Caption = 'libTextSuite'
OnCreate = FormCreate


+ 735
- 20
header/examples/fpc/uMainForm.pas View File

@@ -2,23 +2,77 @@ unit uMainForm;

{$mode objfpc}{$H+}

{$IFDEF LINUX}
{$DEFINE USE_FREETYPE}
{$ENDIF}

interface

uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs,
uglcContext, ulibTextSuite;
ulibTextSuite, dglOpenGL
{$IF DEFINED(WIN32) OR DEFINED(WIN64)}
, Windows
{$ELSEIF DEFINED(LINUX)}
, LCLType, LMessages, XUtil, XLib, gdk2x, gtk2, gdk2, WSLCLClasses, X, glib2
, Gtk2Def, Gtk2Int, InterfaceBase, WSControls
{$ENDIF};

type
{$IF DEFINED(LINUX)}
TRenderControl = class(TWinControl)
private
fIntWidget: PGtkWidget;
fVisualID: TVisualID;
fTarget: TWinControl;
protected
function WSCreateHandle({%H-}const WSPrivate: TWSPrivateClass; const AParams: TCreateParams): TLCLIntfHandle;
procedure WSBeforeDestroyHandle;
procedure WndProc(var Message: TLMessage); override;
public
property Widget: PGtkWidget read FIntWidget;
property Target: TWinControl read fTarget write fTarget;
constructor Create(TheOwner: TComponent; const aVisualID: TVisualID); overload;
end;

TWSCustomVisualControl = class(TWSWinControl)
published
class function CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle; override;
class procedure DestroyHandle(const AWinControl: TWinControl); override;
end;
{$ENDIF}

TMainForm = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormPaint(Sender: TObject);
procedure FormResize(Sender: TObject);

private
fCanRender: Boolean;
fHasRenderContext: Boolean;

{$IF DEFINED(WIN32) OR DEFINED(WIN64)}
fDC: HDC;
fRC: HGLRC;
procedure CreateRenderContext;
procedure DestroyRenderContext;
procedure SwapBuffers;
{$ELSEIF DEFINED(LINUX)}
fVisual: PXVisualInfo;
fDisplay: PDisplay;
fWidget: PGtkWidget;
fContext: GLXContext;
fRenderControl: TRenderControl;
procedure CreateRenderContext;
procedure DestroyRenderContext;
procedure SwapBuffers;
{$ENDIF}

private
fContext: TglcContext;
fltsContext: TltsContext;
fltsRenderer: TltsRendererOpenGL;
fltsCreator: TltsFontCreatorGDI;
fltsCreator: {$IFDEF USE_FREETYPE}TltsFontCreatorFreeType{$ELSE}TltsFontCreatorGDI{$ENDIF};
fltsFont: TltsFont;
fltsPostProcessorList: TltsPostProcessorList;
procedure Render;
@@ -31,9 +85,6 @@ implementation

{$R *.lfm}

uses
dglOpenGL;

const
{$IF DEFINED(WIN32)}
LibName = '..\..\..\libTextSuite-i386-win32.dll';
@@ -55,29 +106,497 @@ const
$7F, $BF, $FF, $BF,
$BF, $7F, $BF, $FF);

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
{$IFDEF LINUX}
type
TGLIntArray = packed array of GLInt;

PGtkCustomWidget = ^TGtkCustomWidget;
TGtkCustomWidget = record
darea: TGtkDrawingArea;
end;

PGtkCustomWidgetClass = ^TGtkCustomWidgetClass;
TGtkCustomWidgetClass = record
parent_class: TGtkDrawingAreaClass;
end;

var
custom_widget_type: TGtkType = 0;
custom_widget_parent_class: Pointer = nil;

function GTK_TYPE_CUSTOM_WIDGET: TGtkType; forward;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure g_return_if_fail(b: boolean; const Msg: string);
begin
if not b then raise Exception.Create(Msg);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure g_return_if_fail(b: boolean);
begin
g_return_if_fail(b,'');
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function GTK_IS_CUSTOM_WIDGET(obj: Pointer): Boolean;
begin
GTK_IS_CUSTOM_WIDGET:=GTK_CHECK_TYPE(obj,GTK_TYPE_CUSTOM_WIDGET);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function GTK_CUSTOM_WIDGET(obj: Pointer): PGtkCustomWidget;
begin
g_return_if_fail(GTK_IS_CUSTOM_WIDGET(obj),'');
Result := PGtkCustomWidget(obj);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure gtk_custom_widget_init(custom_widget: PGTypeInstance; theClass: gpointer); cdecl;
begin
gtk_widget_set_double_buffered(PGtkWidget(custom_widget),gdkFALSE);
GTK_WIDGET_UNSET_FLAGS(PGtkWidget(custom_widget),GTK_NO_WINDOW);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure gtk_custom_widget_destroy(obj: PGtkObject); cdecl;
begin
g_return_if_fail (obj <>nil,'');
g_return_if_fail (GTK_IS_CUSTOM_WIDGET(obj),'');

if Assigned(GTK_OBJECT_CLASS(custom_widget_parent_class)^.destroy) then
GTK_OBJECT_CLASS(custom_widget_parent_class)^.destroy(obj);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure gtk_custom_widget_class_init(klass: Pointer); cdecl;
var
object_class: PGtkObjectClass;
begin
custom_widget_parent_class := gtk_type_class(gtk_drawing_area_get_type());
g_return_if_fail(custom_widget_parent_class<>nil,'gtk_custom_widget_class_init parent_class=nil');
object_class := PGtkObjectClass(klass);
g_return_if_fail(object_class<>nil,'gtk_custom_widget_class_init object_class=nil');
object_class^.destroy := @gtk_custom_widget_destroy;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function custom_widget_size_allocateCB(Widget: PGtkWidget; Size: pGtkAllocation; Data: gPointer): GBoolean; cdecl;
const
CallBackDefaultReturn = {$IFDEF GTK2}false{$ELSE}true{$ENDIF};
var
SizeMsg: TLMSize;
GtkWidth, GtkHeight: integer;
LCLControl: TWinControl;
begin
Result := CallBackDefaultReturn;
if not GTK_WIDGET_REALIZED(Widget) then begin
// the widget is not yet realized, so this GTK resize was not a user change.
// => ignore
exit;
end;
if Size=nil then ;
LCLControl:=TWinControl(Data);
if LCLControl=nil then exit;
//DebugLn(['gtkglarea_size_allocateCB ',DbgSName(LCLControl)]);

gtk_widget_get_size_request(Widget, @GtkWidth, @GtkHeight);

SizeMsg.Msg:=0;
FillChar(SizeMsg,SizeOf(SizeMsg),0);
with SizeMsg do
begin
Result := 0;
Msg := LM_SIZE;
SizeType := Size_SourceIsInterface;
Width := SmallInt(GtkWidth);
Height := SmallInt(GtkHeight);
end;
//DebugLn(['gtkglarea_size_allocateCB ',GtkWidth,',',GtkHeight]);
LCLControl.WindowProc(TLMessage(SizeMsg));
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function GTK_TYPE_CUSTOM_WIDGET: TGtkType;
const
custom_widget_type_name = 'GtkGLArea';
custom_widget_info: TGtkTypeInfo = (
type_name: custom_widget_type_name;
object_size: SizeOf(TGtkCustomWidget);
class_size: SizeOf(TGtkCustomWidgetClass);
class_init_func: @gtk_custom_widget_class_init;
object_init_func: @gtk_custom_widget_init;
reserved_1: nil;
reserved_2: nil;
base_class_init_func: nil;);
begin
if (custom_widget_type=0) then begin
custom_widget_type:=gtk_type_unique(gtk_drawing_area_get_type(),@custom_widget_info);
end;
Result:=custom_widget_type;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function CreateOpenGLContextAttrList(UseFB: boolean; aDoubleBuffered: Boolean; aColorBits, aDepthBits: Integer): TGLIntArray;
var
p: integer;

procedure Add(i: integer);
begin
SetLength(Result, p+1);
Result[p]:=i;
inc(p);
end;

procedure CreateList;
begin
if UseFB then begin Add(GLX_X_RENDERABLE); Add(1); end;
if aDoubleBuffered then begin
if UseFB then begin
Add(GLX_DOUBLEBUFFER); Add(1);
end else
Add(GLX_DOUBLEBUFFER);
end;
if not UseFB and (aColorBits > 24) then Add(GLX_RGBA);
if UseFB then begin
Add(GLX_DRAWABLE_TYPE);
Add(GLX_WINDOW_BIT);
end;
Add(GLX_RED_SIZE); Add(8);
Add(GLX_GREEN_SIZE); Add(8);
Add(GLX_BLUE_SIZE); Add(8);
if (aColorBits > 24) then
Add(GLX_ALPHA_SIZE); Add(8);
Add(GLX_DEPTH_SIZE); Add(aDepthBits);
Add(GLX_STENCIL_SIZE); Add(0);
Add(GLX_AUX_BUFFERS); Add(0);

Add(0); { 0 = X.None (be careful: GLX_NONE is something different) }
end;

begin
SetLength(Result, 0);
p := 0;
CreateList;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function FBglXChooseVisual(dpy:PDisplay; screen:longint; attrib_list:Plongint):PXVisualInfo;
type
PGLXFBConfig = ^GLXFBConfig;
var
FBConfigsCount: integer;
FBConfigs: PGLXFBConfig;
FBConfig: GLXFBConfig;
begin
Result:= nil;
FBConfigsCount:=0;
FBConfigs:= glXChooseFBConfig(dpy, screen, attrib_list, @FBConfigsCount);
if FBConfigsCount = 0 then
exit;

{ just choose the first FB config from the FBConfigs list.
More involved selection possible. }
FBConfig := FBConfigs^;
Result:=glXGetVisualFromFBConfig(dpy, FBConfig);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TRenderControl////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
function TRenderControl.WSCreateHandle(const WSPrivate: TWSPrivateClass; const AParams: TCreateParams): TLCLIntfHandle;
var
cmap: PGdkColormap;
gdkvis: PGdkVisual;
begin
// is the requested VisualID different from what the widget would get?
cmap := gdk_colormap_get_system;
gdkvis:= gdk_colormap_get_visual(cmap);
if XVisualIDFromVisual(gdk_x11_visual_get_xvisual(gdkvis)) <> FVisualID then begin
gdkvis := gdkx_visual_get(FVisualID);
cmap := gdk_colormap_new(gdkvis, false);
end;

fIntWidget := gtk_type_new(GTK_TYPE_CUSTOM_WIDGET);
gtk_widget_set_colormap(fIntWidget, cmap);

Result := TLCLIntfHandle({%H-}PtrUInt(fIntWidget));
PGtkobject(fIntWidget)^.flags:= PGtkobject(fIntWidget)^.flags or GTK_CAN_FOCUS;
TGTK2WidgetSet(WidgetSet).FinishCreateHandle(Self,fIntWidget,AParams);
g_signal_connect_after(fIntWidget, 'size-allocate', TGTKSignalFunc(@custom_widget_size_allocateCB), Self);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TRenderControl.WSBeforeDestroyHandle;
begin
if not HandleAllocated then exit;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TRenderControl.WndProc(var Message: TLMessage);
begin
case Message.msg of
//LM_ACTIVATEITEM,
//LM_CHANGED,
//LM_FOCUS,
LM_CLICKED,
//LM_RELEASED,
LM_ENTER,
LM_LEAVE,
//LM_CHECKRESIZE,
//LM_SETEDITABLE,
//LM_MOVEWORD,
//LM_MOVEPAGE,
//LM_MOVETOROW,
//LM_MOVETOCOLUMN,
//LM_KILLCHAR,
//LM_KILLWORD,
//LM_KILLLINE,
//LM_CLOSEQUERY,
//LM_DRAGSTART,
//LM_MONTHCHANGED,
//LM_YEARCHANGED,
//LM_DAYCHANGED,
LM_LBUTTONTRIPLECLK,
LM_LBUTTONQUADCLK,
LM_MBUTTONTRIPLECLK,
LM_MBUTTONQUADCLK,
LM_RBUTTONTRIPLECLK,
LM_RBUTTONQUADCLK,
LM_MOUSEENTER,
LM_MOUSELEAVE,
LM_XBUTTONTRIPLECLK,
LM_XBUTTONQUADCLK,

//SC_SIZE,
//SC_MOVE,
//SC_MINIMIZE,
//SC_MAXIMIZE,
//SC_NEXTWINDOW,
//SC_PREVWINDOW,
//SC_CLOSE,
SC_VSCROLL,
SC_HSCROLL,
SC_MOUSEMENU,
SC_KEYMENU,
//SC_ARRANGE,
//SC_RESTORE,
//SC_TASKLIST,
//SC_SCREENSAVE,
//SC_HOTKEY,
//SC_DEFAULT,
//SC_MONITORPOWER,
//SC_CONTEXTHELP,
//SC_SEPARATOR,

//LM_MOVE,
//LM_SIZE,
LM_ACTIVATE,
LM_SETFOCUS,
LM_KILLFOCUS,
//LM_ENABLE,
//LM_GETTEXTLENGTH,
//LM_SHOWWINDOW,
//LM_CANCELMODE,
//LM_DRAWITEM,
//LM_MEASUREITEM,
//LM_DELETEITEM,
//LM_VKEYTOITEM,
//LM_CHARTOITEM,
//LM_COMPAREITEM,
//LM_WINDOWPOSCHANGING,
//LM_WINDOWPOSCHANGED,
//LM_NOTIFY,
//LM_HELP,
//LM_NOTIFYFORMAT,
//LM_CONTEXTMENU,
//LM_NCCALCSIZE,
//LM_NCHITTEST,
//LM_NCPAINT,
//LM_NCACTIVATE,
//LM_GETDLGCODE,
LM_NCMOUSEMOVE,
LM_NCLBUTTONDOWN,
LM_NCLBUTTONUP,
LM_NCLBUTTONDBLCLK,
LM_KEYDOWN,
LM_KEYUP,
LM_CHAR,
LM_SYSKEYDOWN,
LM_SYSKEYUP,
LM_SYSCHAR,
LM_COMMAND,
LM_SYSCOMMAND,
LM_TIMER,
LM_HSCROLL,
LM_VSCROLL,
//LM_CTLCOLORMSGBOX,
//LM_CTLCOLOREDIT,
//LM_CTLCOLORLISTBOX,
//LM_CTLCOLORBTN,
//LM_CTLCOLORDLG,
//LM_CTLCOLORSCROLLBAR,
//LM_CTLCOLORSTATIC,
LM_MOUSEMOVE,
LM_LBUTTONDOWN,
LM_LBUTTONUP,
LM_LBUTTONDBLCLK,
LM_RBUTTONDOWN,
LM_RBUTTONUP,
LM_RBUTTONDBLCLK,
LM_MBUTTONDOWN,
LM_MBUTTONUP,
LM_MBUTTONDBLCLK,
LM_MOUSEWHEEL,
LM_XBUTTONDOWN,
LM_XBUTTONUP,
LM_XBUTTONDBLCLK,
//LM_PARENTNOTIFY,
//LM_CAPTURECHANGED,
//LM_DROPFILES,
//LM_SELCHANGE,
LM_CUT,
LM_COPY,
LM_PASTE,
//LM_CLEAR,
//LM_CONFIGUREEVENT,
//LM_EXIT,
//LM_QUIT,
//LM_NULL,
//LM_PAINT,
//LM_ERASEBKGND,
//LM_SETCURSOR,
//LM_SETFONT:

//CM_ACTIVATE,
//CM_DEACTIVATE,
//CM_FOCUSCHANGED,
//CM_PARENTFONTCHANGED,
//CM_PARENTCOLORCHANGED,
//CM_HITTEST,
//CM_VISIBLECHANGED,
//CM_ENABLEDCHANGED,
//CM_COLORCHANGED,
//CM_FONTCHANGED,
//CM_CURSORCHANGED,
//CM_TEXTCHANGED,
CM_MOUSEENTER,
CM_MOUSELEAVE,
//CM_MENUCHANGED,
//CM_APPSYSCOMMAND,
//CM_BUTTONPRESSED,
//CM_SHOWINGCHANGED,
//CM_ENTER,
//CM_EXIT,
//CM_DESIGNHITTEST,
//CM_ICONCHANGED,
//CM_WANTSPECIALKEY,
//CM_RELEASE,
//CM_FONTCHANGE,
//CM_TABSTOPCHANGED,
//CM_UIACTIVATE,
//CM_CONTROLLISTCHANGE,
//CM_GETDATALINK,
//CM_CHILDKEY,
//CM_HINTSHOW,
//CM_SYSFONTCHANGED,
//CM_CONTROLCHANGE,
//CM_CHANGED,
//CM_BORDERCHANGED,
//CM_BIDIMODECHANGED,
//CM_PARENTBIDIMODECHANGED,
//CM_ALLCHILDRENFLIPPED,
//CM_ACTIONUPDATE,
//CM_ACTIONEXECUTE,
//CM_HINTSHOWPAUSE,
//CM_DOCKNOTIFICATION,
CM_MOUSEWHEEL,
//CM_APPSHOWBTNGLYPHCHANGED,
//CM_APPSHOWMENUGLYPHCHANGED,

//CN_BASE,
//CN_CHARTOITEM,
//CN_COMMAND,
//CN_COMPAREITEM,
//CN_CTLCOLORBTN,
//CN_CTLCOLORDLG,
//CN_CTLCOLOREDIT,
//CN_CTLCOLORLISTBOX,
//CN_CTLCOLORMSGBOX,
//CN_CTLCOLORSCROLLBAR,
//CN_CTLCOLORSTATIC,
//CN_DELETEITEM,
//CN_DRAWITEM,
CN_HSCROLL,
//CN_MEASUREITEM,
//CN_PARENTNOTIFY,
//CN_VKEYTOITEM,
CN_VSCROLL,
CN_KEYDOWN,
CN_KEYUP,
CN_CHAR,
CN_SYSKEYUP,
CN_SYSKEYDOWN,
CN_SYSCHAR,
CN_NOTIFY:
begin
if Assigned(fTarget) then
Message.Result := fTarget.Perform(Message.msg, Message.wParam, Message.lParam);
end;
end;
inherited WndProc(Message);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
constructor TRenderControl.Create(TheOwner: TComponent; const aVisualID: TVisualID);
begin
inherited Create(TheOwner);
fIntWidget := nil;
fVisualID := aVisualID;
SetBounds(0, 0, 200, 200);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TWSCustomVisualControl////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class function TWSCustomVisualControl.CreateHandle(const AWinControl: TWinControl; const AParams: TCreateParams): TLCLIntfHandle;
begin
if csDesigning in AWinControl.ComponentState then begin
// do not use "inherited CreateHandle", because the LCL changes the hierarchy at run time
Result:= TWSWinControlClass(ClassParent).CreateHandle(AWinControl,AParams);
end else
Result:= (AWinControl as TRenderControl).WSCreateHandle(WSPrivate, AParams);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class procedure TWSCustomVisualControl.DestroyHandle(const AWinControl: TWinControl);
begin
(AWinControl as TRenderControl).WSBeforeDestroyHandle;
// do not use "inherited DestroyHandle", because the LCL changes the hierarchy at run time
TWSWinControlClass(ClassParent).DestroyHandle(AWinControl);
end;
{$ENDIF}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//MainForm//////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TMainForm.FormCreate(Sender: TObject);
var
pf: TglcContextPixelFormatSettings;
pp: TltsPostProcessor;
img: TltsImage;
begin
ltsInitialize(LibName);

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

CreateRenderContext;
glDisable(GL_DEPTH_TEST);
glDisable(GL_CULL_FACE);
glClearColor(1.0, 1.0, 1.0, 1.0);

ltsInitialize(LibName);
Caption := 'libTextSuite example (Version: ' + ltsGetVersion() + ')';

fltsContext := TltsContext.Create;
fltsRenderer := TltsRendererOpenGL.Create(fltsContext, ltsFormatRGBA8);
fltsCreator := TltsFontCreatorGDI.Create(fltsContext);
fltsCreator := {$IFDEF USE_FREETYPE}TltsFontCreatorFreeType{$ELSE}TltsFontCreatorGDI{$ENDIF}.Create(fltsContext);

fltsPostProcessorList := TltsPostProcessorList.Create(fltsContext, true);

@@ -98,6 +617,8 @@ begin

fltsFont := fltsCreator.GetFontByFile(ExpandFileName('../Prototype.ttf'), 40, [], ltsAANormal);
fltsFont.PostProcessor := fltsPostProcessorList;

fCanRender := true;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -108,20 +629,21 @@ begin
FreeAndNil(fltsCreator);
FreeAndNil(fltsRenderer);
FreeAndNil(fltsContext);
FreeAndNil(fContext);
ltsFinalize;
DestroyRenderContext;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TMainForm.FormPaint(Sender: TObject);
begin
Render;
if fCanRender then
Render;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TMainForm.FormResize(Sender: TObject);
begin
if Assigned(fContext) then begin
if fHasRenderContext then begin
glViewport(0, 0, ClientWidth, ClientHeight);
glMatrixMode(GL_PROJECTION);
glLoadIdentity;
@@ -131,6 +653,195 @@ begin
end;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
{$IF DEFINED(WIN32) OR DEFINED(WIN64)}
procedure TMainForm.CreateRenderContext;

function FindPixelFormat: Integer;
const
MemoryDCs = [OBJ_MEMDC, OBJ_METADC, OBJ_ENHMETADC];
var
AType: DWord;
PFDescriptor: TPixelFormatDescriptor;
begin
result := 0;
FillChar(PFDescriptor{%H-}, SizeOf(PFDescriptor), #0);
with PFDescriptor do begin
nSize := SizeOf(PFDescriptor);
nVersion := 1;
dwFlags := PFD_SUPPORT_OPENGL;
AType := GetObjectType(fDC);
if AType = 0 then
raise Exception.Create('unable to get device context object type');
dwFlags := dwFlags or PFD_DOUBLEBUFFER;
if AType in MemoryDCs then
dwFlags := dwFlags or PFD_DRAW_TO_BITMAP
else
dwFlags := dwFlags or PFD_DRAW_TO_WINDOW;

iPixelType := PFD_TYPE_RGBA;
cColorBits := 32;
cDepthBits := 24;
cStencilBits := 0;
cAccumBits := 0;
cAuxBuffers := 0;
iLayerType := PFD_MAIN_PLANE;
end;
result := ChoosePixelFormat(fDC, @PFDescriptor);
end;

var
pf: Integer;
err: DWORD;
begin
InitOpenGL;

fDC := GetDC(Handle);
if (fDC = 0) then
raise Exception.Create('unable to get device context');

pf := FindPixelFormat;
if not SetPixelFormat(fDC, pf, nil) then begin
ReleaseDC(Handle, fDC);
raise Exception.CreateFmt('Cannot set PF %d on Control %x DC %d', [pf, Handle, FDC]);
end;

fRC := wglCreateContext(FDC);
if (fRC = 0) then begin
ReleaseDC(Handle, FDC);
raise Exception.CreateFmt('Cannot create context on Control %x DC %d', [pf, Handle, FDC]);
end;

if not wglMakeCurrent(fDC, fRC) then begin
err := GetLastError;
raise Exception.Create('unable to activate context: (' + IntToStr(err) + ') ' + SysErrorMessage(err));
end;

ReadOpenGLCore;
ReadExtensions;
ReadImplementationProperties;

fHasRenderContext := true;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TMainForm.DestroyRenderContext;
begin
wglMakeCurrent(0, 0);
DestroyRenderingContext(fRC);
ReleaseDC(Handle, fDC);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TMainForm.SwapBuffers;
begin
Windows.SwapBuffers(fDC);
end;

{$ELSEIF DEFINED(LINUX)}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TMainForm.CreateRenderContext;

procedure UpdateVisual;
var
attrList: TGLIntArray;
drawable: PGdkDrawable;
begin
{ Temporary (realized) widget to get to display }
fWidget:= {%H-}PGtkWidget(PtrUInt(Handle));
gtk_widget_realize(fWidget);
drawable := GTK_WIDGET(fWidget)^.window;
fDisplay := GDK_WINDOW_XDISPLAY(drawable);

{ Find a suitable visual from PixelFormat using GLX 1.3 FBConfigs or
old-style Visuals }
if Assigned(glXChooseFBConfig) then begin
attrList := CreateOpenGLContextAttrList(true, true, 32, 24);
fVisual := FBglXChooseVisual(FDisplay, DefaultScreen(FDisplay), @attrList[0]);
end;
if not Assigned(fVisual) then begin
attrList := CreateOpenGLContextAttrList(false, true, 32, 24);
fVisual := glXChooseVisual(FDisplay, DefaultScreen(FDisplay), @attrList[0]);
end;
if not Assigned(fVisual) then
raise Exception.Create('choose visual failed');

{ Most widgets inherit the drawable of their parent. In contrast to Windows, descending from
TWinControl does not mean it's actually always a window of its own.
Famous example: TPanel is just a frame painted on a canvas.
Also, the LCL does somethin weird to colormaps in window creation, so we have
to use a custom widget here to have full control about visual selection. }
fRenderControl:= TRenderControl.Create(self, fVisual^.visual^.visualid);
try
fRenderControl.Parent := self;
fRenderControl.HandleNeeded;
fRenderControl.Target := self;
except
FreeAndNil(fRenderControl);
raise;
end;

{ Real Widget handle, unrealized!!! }
fWidget := fRenderControl.Widget;
gtk_widget_realize(fWidget);
drawable := GTK_WIDGET(fWidget)^.window;
FDisplay := GDK_WINDOW_XDISPLAY(drawable);

// fRenderControl.Align:= alClient breaks the context or something
fRenderControl.BoundsRect := ClientRect;
fRenderControl.Anchors := [akLeft, akTop, akRight, akBottom];
end;

var
glxID: GLXDrawable;
begin
InitOpenGL;
UpdateVisual;
if not Assigned(FVisual) then
raise Exception.Create('Failed to find Visual');

fContext := glXCreateContext(FDisplay, FVisual, nil, true);
if not Assigned(fContext) then
raise Exception.Create('Failed to create Context');

gtk_widget_realize(fWidget);
if not GTK_WIDGET_REALIZED(fWidget) then
exit;

glxID := GDK_DRAWABLE_XID(GTK_WIDGET(fWidget)^.window);
glXMakeCurrent(fDisplay, glxID, fContext);

ReadOpenGLCore;
ReadExtensions;
ReadImplementationProperties;

fHasRenderContext := true;
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TMainForm.DestroyRenderContext;
var
glxID: GLXDrawable;
begin
glxID := GDK_DRAWABLE_XID(GTK_WIDGET(fWidget)^.window);
glXMakeCurrent(FDisplay, glxID, nil);
if Assigned(fContext) then
glXDestroyContext(fDisplay, fContext);
FreeAndNil(fRenderControl);
end;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TMainForm.SwapBuffers;
var
glxID: GLXDrawable;
begin
if not Assigned(fWidget) then
exit;
glxID := GDK_DRAWABLE_XID(GTK_WIDGET(fWidget)^.window);
glXSwapBuffers(fDisplay, glxID);
end;
{$ENDIF}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure TMainForm.Render;
var
@@ -152,8 +863,12 @@ begin
fltsRenderer.EndBlock(block);
end;

fContext.SwapBuffers;
SwapBuffers;
end;

end.
{$IFDEF LINUX}
initialization
RegisterWSComponent(TRenderControl, TWSCustomVisualControl);
{$ENDIF}

end.

+ 30
- 19
header/libTextSuite.h View File

@@ -2,19 +2,27 @@
#define LIB_TEXT_SUITE_H

#include <stdint.h>
#include <string.h>
#include <stdbool.h>
#include <wchar.h>

#if __MINGW32__
# define WINAPI __stdcall
# define WINAPI __stdcall
#elif __GNUC__
# if defined(__x86_64__)
# define WINAPI
# else
# define WINAPI __attribute__((stdcall))
# endif
#else
# define WINAPI
# define WINAPI
#endif

#define STATIC_ASSERT(cond, msg) typedef char static_assertion_##msg[(cond)?1:-1]

STATIC_ASSERT(sizeof(float) == 4, size_of_float_should_be_4);
STATIC_ASSERT(sizeof(wchar_t) == 2, size_of_wchar_t_should_be_4);
typedef uint16_t lts_wchar_t;

STATIC_ASSERT(sizeof(float) == 4, size_of_float_should_be_4);
STATIC_ASSERT(sizeof(lts_wchar_t) == 2, size_of_wchar_t_should_be_2);

/**********************************************************************************************************************************/
/* public interface */
@@ -284,7 +292,7 @@ typedef struct
int32_t size;
lts_font_style_flags_t style;
lts_anti_aliasing_t anti_aliasing;
wchar_t default_char;
lts_wchar_t default_char;
uint8_t __reserved[2];
int32_t ascent;
@@ -371,10 +379,10 @@ typedef void (WINAPI *lts_image_blend_callback_t)(lts_image_handle_t handle, lts
/* callbacks **********************************************************************************************************************/
lts_context_handle_t (WINAPI *lts_context_create) ();
lts_error_code_t (WINAPI *lts_context_get_code_page) (lts_context_handle_t handle, lts_code_page_t* value);
lts_error_code_t (WINAPI *lts_context_get_default_char) (lts_context_handle_t handle, wchar_t* value);
lts_error_code_t (WINAPI *lts_context_get_default_char) (lts_context_handle_t handle, lts_wchar_t* value);
lts_error_code_t (WINAPI *lts_context_set_code_page) (lts_context_handle_t handle, lts_code_page_t value);
lts_error_code_t (WINAPI *lts_context_set_default_char) (lts_context_handle_t handle, wchar_t value);
wchar_t* (WINAPI *lts_context_ansi_to_wide) (lts_context_handle_t handle, const char* text);
lts_error_code_t (WINAPI *lts_context_set_default_char) (lts_context_handle_t handle, lts_wchar_t value);
lts_wchar_t* (WINAPI *lts_context_ansi_to_wide) (lts_context_handle_t handle, const char* text);
lts_error_code_t (WINAPI *lts_context_destroy) (lts_context_handle_t handle);
lts_renderer_handle_t (WINAPI *lts_renderer_create) (lts_context_handle_t handle, lts_renderer_type_t type, lts_format_t format);
@@ -383,7 +391,7 @@ lts_text_block_handle_t (WINAPI *lts_renderer_begin_block)
lts_error_code_t (WINAPI *lts_renderer_end_block) (lts_renderer_handle_t handle, lts_text_block_handle_t block);
lts_error_code_t (WINAPI *lts_renderer_abort_block) (lts_renderer_handle_t handle, lts_text_block_handle_t block);
int (WINAPI *lts_renderer_get_text_width_a) (lts_renderer_handle_t handle, lts_font_handle_t font, const char* text);
int (WINAPI *lts_renderer_get_text_width_w) (lts_renderer_handle_t handle, lts_font_handle_t font, const wchar_t* text);
int (WINAPI *lts_renderer_get_text_width_w) (lts_renderer_handle_t handle, lts_font_handle_t font, const lts_wchar_t* text);
lts_error_code_t (WINAPI *lts_renderer_destroy) (lts_renderer_handle_t handle);

lts_font_creator_handle_t (WINAPI *lts_font_creator_create) (lts_context_handle_t handle, lts_font_creator_type_t type);
@@ -428,9 +436,9 @@ lts_error_code_t (WINAPI *lts_text_block_set_color)
lts_error_code_t (WINAPI *lts_text_block_set_font) (lts_text_block_handle_t handle, lts_font_handle_t value);
int (WINAPI *lts_text_block_get_actual_height) (lts_text_block_handle_t handle);
int (WINAPI *lts_text_block_get_text_width_a) (lts_text_block_handle_t handle, const char* text);
int (WINAPI *lts_text_block_get_text_width_w) (lts_text_block_handle_t handle, const wchar_t* text);
int (WINAPI *lts_text_block_get_text_width_w) (lts_text_block_handle_t handle, const lts_wchar_t* text);
lts_error_code_t (WINAPI *lts_text_block_text_out_a) (lts_text_block_handle_t handle, const char* text);
lts_error_code_t (WINAPI *lts_text_block_text_out_w) (lts_text_block_handle_t handle, const wchar_t* text);
lts_error_code_t (WINAPI *lts_text_block_text_out_w) (lts_text_block_handle_t handle, const lts_wchar_t* text);
lts_error_code_t (WINAPI *lts_text_block_destroy) (lts_text_block_handle_t handle);

lts_image_handle_t (WINAPI *lts_image_create) (lts_context_handle_t handle);
@@ -453,8 +461,8 @@ lts_error_code_t (WINAPI *lts_image_blend)
lts_error_code_t (WINAPI *lts_image_blur) (lts_image_handle_t handle, float horzRad, float horzStr, float vertRad, float vertStr, lts_color_channel_flags_t mask);
lts_error_code_t (WINAPI *lts_image_destroy) (lts_image_handle_t handle);

lts_error_code_t (WINAPI *lts_post_processor_add_range) (lts_post_processor_handle_t handle, lts_char_range_usage_t usage, wchar_t start, wchar_t stop);
lts_error_code_t (WINAPI *lts_post_processor_add_chars) (lts_post_processor_handle_t handle, lts_char_range_usage_t usage, const wchar_t* chars);
lts_error_code_t (WINAPI *lts_post_processor_add_range) (lts_post_processor_handle_t handle, lts_char_range_usage_t usage, lts_wchar_t start, lts_wchar_t stop);
lts_error_code_t (WINAPI *lts_post_processor_add_chars) (lts_post_processor_handle_t handle, lts_char_range_usage_t usage, const lts_wchar_t* chars);
lts_error_code_t (WINAPI *lts_post_processor_clear_ranges) (lts_post_processor_handle_t handle);
lts_error_code_t (WINAPI *lts_post_processor_execute) (lts_post_processor_handle_t handle, lts_char_handle_t charHandle, lts_image_handle_t image);
lts_post_processor_handle_t (WINAPI *lts_post_processor_fill_color_create) (lts_post_processor_handle_t handle, lts_color4f_t color, lts_image_modes_t modes, lts_color_channel_flags_t channels);
@@ -464,10 +472,11 @@ lts_post_processor_handle_t (WINAPI *lts_post_processor_shadow_create)
lts_post_processor_handle_t (WINAPI *lts_post_processor_custom_create) (lts_post_processor_handle_t handle, const lts_post_processor_custom_data_t* data);
lts_error_code_t (WINAPI *lts_post_processor_destroy) (lts_post_processor_handle_t handle);

lts_error_code_t (WINAPI *lts_char_get_char_code) (lts_char_handle_t handle, wchar_t* value);
lts_error_code_t (WINAPI *lts_char_get_char_code) (lts_char_handle_t handle, lts_wchar_t* value);
lts_error_code_t (WINAPI *lts_char_get_glyph_metric) (lts_char_handle_t handle, lts_glyph_metric_t* value);
lts_error_code_t (WINAPI *lts_char_set_glyph_metric) (lts_char_handle_t handle, const lts_glyph_metric_t* value);

const char* (WINAPI *lts_get_version) ();
lts_error_code_t (WINAPI *lts_get_last_error_code) ();
const char* (WINAPI *lts_get_last_error_msg) ();

@@ -502,16 +511,16 @@ const char* (WINAPI *lts_get_last_error_msg)
FLAGS_MAKE(ltsColorChannelAlpha);

/* helper *************************************************************************************************************************/
inline lts_color4f_t ltsColor4f(float r, float g, float b, float a)
static inline lts_color4f_t ltsColor4f(float r, float g, float b, float a)
{ lts_color4f_t ret = { r, g, b, a }; return ret; };

inline lts_position_t ltsPosition(int x, int y)
static inline lts_position_t ltsPosition(int x, int y)
{ lts_position_t ret = { x, y }; return ret; };
inline lts_rect_t ltsRect(int left, int top, int right, int bottom)
static inline lts_rect_t ltsRect(int left, int top, int right, int bottom)
{ lts_rect_t ret = { left, top, right, bottom }; return ret; };

inline lts_rect_t ltsRectFromPos(lts_position_t leftTop, lts_position_t bottomRight)
static inline lts_rect_t ltsRectFromPos(lts_position_t leftTop, lts_position_t bottomRight)
{ lts_rect_t ret = { leftTop.x, leftTop.y, bottomRight.x, bottomRight.y }; return ret; };

/**********************************************************************************************************************************/
@@ -686,6 +695,7 @@ lts_error_code_t lts_initialize(const char* libname)
LoadProc(lts_char_set_glyph_metric, "ltsCharSetGlyphMetric");
LoadProc(lts_initialize_intern, "ltsInitialize");
LoadProc(lts_get_version, "ltsGetVersion");
LoadProc(lts_get_last_error_code, "ltsGetLastErrorCode");
LoadProc(lts_get_last_error_msg, "ltsGetLastErrorMsg");
LoadProc(lts_finalize_intern, "ltsFinalize");
@@ -797,6 +807,7 @@ int lts_finalize(void)
lts_char_set_glyph_metric = NULL;
lts_initialize_intern = NULL;
lts_get_version = NULL;
lts_get_last_error_code = NULL;
lts_get_last_error_msg = NULL;
lts_finalize_intern = NULL;


+ 54
- 31
header/libTextSuite.hpp View File

@@ -8,6 +8,12 @@
#include <stdint.h>
#include <initializer_list>

#if __MINGW32__
# define packed
#else
# define packed __attribute__((packed))
#endif

#if defined(WIN32) || defined(WIN64) || defined(_WIN32) || defined(_WIN64)
# define LTS_WINDOWS
# include <windows.h>
@@ -30,18 +36,19 @@
namespace lts
{
/* simple types *******************************************************************************************************************/
typedef wchar_t WideChar;
typedef void* RenderRef;
typedef void* Handle;
typedef Handle ContextHandle;
typedef Handle RendererHandle;
typedef Handle TextBlockHandle;
typedef Handle FontCreatorHandle;
typedef Handle FontHandle;
typedef Handle PostProcessorHandle;
typedef Handle ImageHandle;
typedef Handle CharHandle;

typedef void* RenderRef;
typedef void* Handle;
typedef Handle ContextHandle;
typedef Handle RendererHandle;
typedef Handle TextBlockHandle;
typedef Handle FontCreatorHandle;
typedef Handle FontHandle;
typedef Handle PostProcessorHandle;
typedef Handle ImageHandle;
typedef Handle CharHandle;
typedef uint16_t WideChar;
typedef std::basic_string<WideChar> wstring;
/* enumerations *******************************************************************************************************************/
enum class ErrorCode : int32_t
{
@@ -247,7 +254,7 @@ namespace lts
for (auto i = begIt; i != endIt; ++i)
set(*i);
};
};
} packed;
enum class BlockFlag
{
@@ -284,28 +291,28 @@ namespace lts
{
int x;
int y;
};
} packed;
static_assert(sizeof(Position) == 8, "size of lts::Position should be 8");
union Rect
{
struct { Position top_left, bottom_right; };
struct { int32_t left, top, right, bottom; };
};
} packed;
static_assert(sizeof(Rect) == 16, "size of lts::Rect should be 16");
union Color4f
{
struct { float r, g, b, a; };
float arr[4];
};
} packed;
static_assert(sizeof(Color4f) == 16, "size of lts::Color4f should be 16");
union ImageModes
{
struct { ImageMode r, g, b, a; };
ImageMode arr[4];
};
} packed;
static_assert(sizeof(ImageModes) == 16, "size of lts::ImageModes should be 16");
struct GlyphMetric
@@ -313,7 +320,7 @@ namespace lts
Position glyphOrigin;
Rect glyphRect;
int32_t advance;
};
} packed;
static_assert(sizeof(GlyphMetric) == 28, "size of lts::GlyphMetric should be 28");
struct TextMetric
@@ -325,7 +332,7 @@ namespace lts
int32_t charSpacing;
int32_t lineHeight;
int32_t lineSpacing;
};
} packed;
static_assert(sizeof(TextMetric) == 28, "size of lts::TextMetric should be 28");
struct FontMetric
@@ -345,7 +352,7 @@ namespace lts
int32_t underlineSize;
int32_t strikeoutPos;
int32_t strikeoutSize;
};
} packed;
static_assert(sizeof(FontMetric) == 48, "size of lts::FontMetric should be 48");
typedef float Vector4f[4];
@@ -411,6 +418,7 @@ namespace lts
Library(const Library& that) = delete;
public:
const Impl& getImpl() const;
std::string getVersion() const;
ErrorCode getLastErrorCode() const;
std::string getLastErrorMsg() const;
@@ -756,12 +764,12 @@ namespace lts
void textOutA(const char* text);
void textOutA(const std::string& text);
void textOutW(const WideChar* text);
void textOutW(const std::wstring& text);
void textOutW(const wstring& text);
int getTextWidthA(const char* text);
int getTextWidthA(const std::string& text);
int getTextWidthW(const WideChar* text);
int getTextWidthW(const std::wstring& text);
int getTextWidthW(const wstring& text);
TextBlock(const Library::Impl& impl, TextBlockHandle handle);
virtual ~TextBlock();
@@ -788,7 +796,7 @@ namespace lts
int getTextWidthA(const Font& font, const char* text);
int getTextWidthA(const Font& font, const std::string& text);
int getTextWidthW(const Font& font, const WideChar* text);
int getTextWidthW(const Font& font, const std::wstring& text);
int getTextWidthW(const Font& font, const wstring& text);
virtual ~Renderer();
};
@@ -1006,7 +1014,7 @@ public: /* callbacks */
typedef lts::ErrorCode (WINAPI *image_blur_t) (lts::ImageHandle handle, float horzRad, float horzStr, float vertRad, float vertStr, uint32_t mask);
typedef lts::ErrorCode (WINAPI *image_destroy_t) (lts::ImageHandle handle);
typedef lts::ErrorCode (WINAPI *post_processor_add_range_t) (lts::PostProcessorHandle handle, lts::CharRangeUsage usage, WideChar start, wchar_t stop);
typedef lts::ErrorCode (WINAPI *post_processor_add_range_t) (lts::PostProcessorHandle handle, lts::CharRangeUsage usage, WideChar start, WideChar stop);
typedef lts::ErrorCode (WINAPI *post_processor_add_chars_t) (lts::PostProcessorHandle handle, lts::CharRangeUsage usage, const WideChar* chars);
typedef lts::ErrorCode (WINAPI *post_processor_clear_ranges_t) (lts::PostProcessorHandle handle);
typedef lts::ErrorCode (WINAPI *post_processor_execute_t) (lts::PostProcessorHandle handle, lts::CharHandle charHandle, lts::ImageHandle image);
@@ -1022,6 +1030,7 @@ public: /* callbacks */
typedef lts::ErrorCode (WINAPI *char_set_glyph_metric_t) (lts::CharHandle handle, const lts::GlyphMetric& value);

typedef lts::ErrorCode (WINAPI *initialize_t) ();
typedef const char* (WINAPI *get_version_t) ();
typedef lts::ErrorCode (WINAPI *get_last_error_code_t) ();
typedef const char* (WINAPI *get_last_error_msg_t) ();
typedef lts::ErrorCode (WINAPI *finalize_t) ();
@@ -1139,6 +1148,7 @@ public:
char_set_glyph_metric_t char_set_glyph_metric;
initialize_t initialize;
get_version_t get_version;
get_last_error_code_t get_last_error_code;
get_last_error_msg_t get_last_error_msg;
finalize_t finalize;
@@ -1246,6 +1256,7 @@ public:
char_get_glyph_metric (NULL),
char_set_glyph_metric (NULL),
get_version (NULL),
get_last_error_code (NULL),
get_last_error_msg (NULL)
{
@@ -1349,6 +1360,7 @@ public:
loadProc(char_set_glyph_metric, "ltsCharSetGlyphMetric");
loadProc(initialize, "ltsInitialize");
loadProc(get_version, "ltsGetVersion");
loadProc(get_last_error_code, "ltsGetLastErrorCode");
loadProc(get_last_error_msg, "ltsGetLastErrorMsg");
loadProc(finalize, "ltsFinalize");
@@ -1367,7 +1379,7 @@ public:
namespace lts
{
template <typename T>
T getFunc(const Library::Impl& impl, Handle handle, ErrorCode (WINAPI * const callback)(Handle, T&))
static inline T getFunc(const Library::Impl& impl, Handle handle, ErrorCode (WINAPI * const callback)(Handle, T&))
{
T value;
auto err = callback(handle, value);
@@ -1376,7 +1388,7 @@ namespace lts
return value;
}
int getFunc(const Library::Impl& impl, Handle handle, int (WINAPI * const callback)(Handle))
static inline int getFunc(const Library::Impl& impl, Handle handle, int (WINAPI * const callback)(Handle))
{
int value = callback(handle);
if (value < 0)
@@ -1385,7 +1397,7 @@ namespace lts
}
template<typename T>
T getFunc(const Library::Impl& impl, Handle handle, T (WINAPI * const callback)(Handle), T invalidValue)
static inline T getFunc(const Library::Impl& impl, Handle handle, T (WINAPI * const callback)(Handle), T invalidValue)
{
T value = callback(handle);
if (value == invalidValue)
@@ -1394,7 +1406,15 @@ namespace lts
}
template <typename T>
void setFunc(const Library::Impl& impl, Handle handle, ErrorCode (WINAPI * const callback)(Handle, T), const T& value)
static inline void setFunc(const Library::Impl& impl, Handle handle, ErrorCode (WINAPI * const callback)(Handle, T), const T& value)
{
auto err = callback(handle, value);
if (err != ErrorCode::None)
throw Exception(impl.get_last_error_msg(), err);
}
template <typename T>
static inline void setFunc(const Library::Impl& impl, Handle handle, ErrorCode (WINAPI * const callback)(Handle, const T&), const T& value)
{
auto err = callback(handle, value);
if (err != ErrorCode::None)
@@ -1424,6 +1444,9 @@ lts::Exception::~Exception() throw()
inline const lts::Library::Impl& lts::Library::getImpl() const
{ return *_impl; };

inline std::string lts::Library::getVersion() const
{ return std::string(_impl->get_version()); }

inline lts::ErrorCode lts::Library::getLastErrorCode() const
{ return _impl->get_last_error_code(); }

@@ -2080,7 +2103,7 @@ inline void lts::TextBlock::textOutA(const std::string& text)
inline void lts::TextBlock::textOutW(const WideChar* text)
{ setFunc(_impl, _handle, _impl.text_block_text_out_w, text); };

inline void lts::TextBlock::textOutW(const std::wstring& text)
inline void lts::TextBlock::textOutW(const wstring& text)
{ setFunc(_impl, _handle, _impl.text_block_text_out_w, text.c_str()); };

int lts::TextBlock::getTextWidthA(const char* text)
@@ -2104,7 +2127,7 @@ int lts::TextBlock::getTextWidthW(const WideChar* text)
throw Exception(_impl.get_last_error_msg(), _impl.get_last_error_code());
};

int lts::TextBlock::getTextWidthW(const std::wstring& text)
int lts::TextBlock::getTextWidthW(const wstring& text)
{
int ret = _impl.text_block_get_text_width_w(_handle, text.c_str());
if (ret < 0)
@@ -2175,7 +2198,7 @@ int lts::Renderer::getTextWidthW(const Font& font, const WideChar* text)
return ret;
}

int lts::Renderer::getTextWidthW(const Font& font, const std::wstring& text)
int lts::Renderer::getTextWidthW(const Font& font, const wstring& text)
{
auto ret = _impl.renderer_get_text_width_w(_handle, font.getHandle(), text.c_str());
if (ret < 0)


+ 5
- 3
header/ulibTextSuite.pas View File

@@ -297,7 +297,7 @@ type
seek: TltsStreamFuncSeek;
end;

TltsPostProcessorExecuteFunc = procedure(const aCharHandle: TltsCharHandle; const aImageHandle: TltsImageHandle; aArgs: Pointer);
TltsPostProcessorExecuteFunc = procedure(const aCharHandle: TltsCharHandle; const aImageHandle: TltsImageHandle; aArgs: Pointer); stdcall;
PltsPostProcessorCustomData = ^TltsPostProcessorCustomData;
TltsPostProcessorCustomData = packed record
args: Pointer;
@@ -436,6 +436,7 @@ type
TltsCharSetGlyphMetric = function(aHandle: TltsCharHandle; constref aValue: TltsGlyphMetric): TltsErrorCode; stdcall;

TltsInitialize = function(): TltsErrorCode; stdcall;
TltsGetVersion = function(): PAnsiChar; stdcall;
TltsGetLastErrorCode = function(): TltsErrorCode; stdcall;
TltsGetLastErrorMsg = function(): PAnsiChar; stdcall;
TltsFinalize = function(): TltsErrorCode; stdcall;
@@ -540,6 +541,7 @@ var
ltsCharGetGlyphMetric: TltsCharGetGlyphMetric;
ltsCharSetGlyphMetric: TltsCharSetGlyphMetric;

ltsGetVersion: TltsGetVersion;
ltsGetLastErrorCode: TltsGetLastErrorCode;
ltsGetLastErrorMsg: TltsGetLastErrorMsg;

@@ -716,7 +718,6 @@ type
destructor Destroy; override;
end;


////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TltsFont = class(TObject)
private
@@ -1171,6 +1172,7 @@ begin
ltsCharSetGlyphMetric := TltsCharSetGlyphMetric( LoadProc('ltsCharSetGlyphMetric'));

ltsInitializeIntern := TltsInitialize( LoadProc('ltsInitialize'));
ltsGetVersion := TltsGetVersion( LoadProc('ltsGetVersion'));
ltsGetLastErrorCode := TltsGetLastErrorCode( LoadProc('ltsGetLastErrorCode'));
ltsGetLastErrorMsg := TltsGetLastErrorMsg( LoadProc('ltsGetLastErrorMsg'));
ltsFinalizeIntern := TltsFinalize( LoadProc('ltsFinalize'));
@@ -1588,7 +1590,7 @@ end;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//TltsPostProcessorCustom///////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
procedure ltsPostProcessorExecuteCallback(const aChar: TltsCharHandle; const aImage: TltsImageHandle; aArgs: Pointer);
procedure ltsPostProcessorExecuteCallback(const aChar: TltsCharHandle; const aImage: TltsImageHandle; aArgs: Pointer); stdcall;
var
chr: TltsChar;
img: TltsImage;


+ 5
- 2
libTextSuite.lpi View File

@@ -428,7 +428,6 @@
<Linking>
<Debugging>
<UseHeaptrc Value="True"/>
<UseExternalDbgSyms Value="True"/>
</Debugging>
<Options>
<ExecutableType Value="Library"/>
@@ -438,7 +437,11 @@
<CompilerMessages>
<IgnoredMessages idx5024="True"/>
</CompilerMessages>
<CustomOptions Value="-dDUMP_HEAPTRACE"/>
<CustomOptions Value="-dDUMP_HEAPTRACE
-dDEBUG"/>
<OtherDefines Count="1">
<Define0 Value="DUMP_HEAPTRACE"/>
</OtherDefines>
</Other>
</CompilerOptions>
<Debugging>


+ 1
- 0
libTextSuite.lpr View File

@@ -108,6 +108,7 @@ exports
ltsCharSetGlyphMetric,

ltsInitialize,
ltsGetVersion,
ltsGetLastErrorCode,
ltsGetLastErrorMsg,
ltsFinalize;


+ 1
- 1
src/TextSuite

@@ -1 +1 @@
Subproject commit c127e64b205e4f3051ea2d703f8bd83782ff9ab2
Subproject commit 81e189737fdd98dff433cf2a2f8fa652801229b7

Loading…
Cancel
Save