@@ -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 |
@@ -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"); | |||
@@ -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 */ |
@@ -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(); | |||
} |
@@ -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) |
@@ -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 |
@@ -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)); | |||
@@ -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 */ |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} |
@@ -55,7 +55,7 @@ | |||
</Target> | |||
<SearchPaths> | |||
<IncludeFiles Value="$(ProjOutDir)"/> | |||
<OtherUnitFiles Value="..\..\..\src\OpenGLCore;..\.."/> | |||
<OtherUnitFiles Value="..\.."/> | |||
<UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/> | |||
</SearchPaths> | |||
<Linking> | |||
@@ -1,7 +1,7 @@ | |||
object MainForm: TMainForm | |||
Left = 876 | |||
Left = 1121 | |||
Height = 500 | |||
Top = 270 | |||
Top = 232 | |||
Width = 640 | |||
Caption = 'libTextSuite' | |||
OnCreate = FormCreate | |||
@@ -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. |
@@ -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; | |||
@@ -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) | |||
@@ -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; | |||
@@ -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> | |||
@@ -108,6 +108,7 @@ exports | |||
ltsCharSetGlyphMetric, | |||
ltsInitialize, | |||
ltsGetVersion, | |||
ltsGetLastErrorCode, | |||
ltsGetLastErrorMsg, | |||
ltsFinalize; | |||
@@ -1 +1 @@ | |||
Subproject commit c127e64b205e4f3051ea2d703f8bd83782ff9ab2 | |||
Subproject commit 81e189737fdd98dff433cf2a2f8fa652801229b7 |