mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-12-25 07:38:54 +00:00
X11TK: Introduce Thai support and rewrite/cleanup messagebox positioning code (#14474)
This commit is contained in:
@@ -349,6 +349,8 @@ dep_option(SDL_X11_XSYNC "Enable Xsync support" ON SDL_X11 OFF)
|
||||
dep_option(SDL_X11_XTEST "Enable XTest support" ON SDL_X11 OFF)
|
||||
dep_option(SDL_FRIBIDI "Enable Fribidi support" ON SDL_X11 OFF)
|
||||
dep_option(SDL_FRIBIDI_SHARED "Dynamically load Fribidi support" ON "SDL_FRIBIDI;SDL_DEPS_SHARED" OFF)
|
||||
dep_option(SDL_LIBTHAI "Enable Thai support" ON SDL_X11 OFF)
|
||||
dep_option(SDL_LIBTHAI_SHARED "Dynamically load Thai support" ON "SDL_LIBTHAI;SDL_DEPS_SHARED" OFF)
|
||||
dep_option(SDL_WAYLAND "Use Wayland video driver" ${UNIX_SYS} "SDL_VIDEO" OFF)
|
||||
dep_option(SDL_WAYLAND_SHARED "Dynamically load Wayland support" ON "SDL_WAYLAND;SDL_DEPS_SHARED" OFF)
|
||||
dep_option(SDL_WAYLAND_LIBDECOR "Use client-side window decorations on Wayland" ON "SDL_WAYLAND" OFF)
|
||||
@@ -1813,6 +1815,7 @@ elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU)
|
||||
CheckROCKCHIP()
|
||||
CheckX11()
|
||||
CheckFribidi()
|
||||
CheckLibThai()
|
||||
# Need to check for EGL first because KMSDRM and Wayland depend on it.
|
||||
CheckEGL()
|
||||
CheckKMSDRM()
|
||||
|
||||
@@ -588,6 +588,31 @@ macro(CheckFribidi)
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(CheckLibThai)
|
||||
if(SDL_LIBTHAI)
|
||||
set(LIBTHAI_PKG_CONFIG_SPEC libthai)
|
||||
set(PC_LIBTHAI_FOUND FALSE)
|
||||
if(PKG_CONFIG_FOUND)
|
||||
pkg_check_modules(PC_LIBTHAI IMPORTED_TARGET ${LIBTHAI_PKG_CONFIG_SPEC})
|
||||
endif()
|
||||
if(PC_LIBTHAI_FOUND)
|
||||
set(HAVE_LIBTHAI TRUE)
|
||||
set(HAVE_LIBTHAI_H 1)
|
||||
if(SDL_LIBTHAI_SHARED AND NOT HAVE_SDL_LOADSO)
|
||||
message(WARNING "You must have SDL_LoadObject() support for dynamic libthai loading")
|
||||
endif()
|
||||
FindLibraryAndSONAME("thai" LIBDIRS ${PC_LIBTHAI_LIBRARY_DIRS})
|
||||
if(SDL_LIBTHAI_SHARED AND THAI_LIB AND HAVE_SDL_LOADSO)
|
||||
set(SDL_LIBTHAI_DYNAMIC "\"${THAI_LIB_SONAME}\"")
|
||||
set(HAVE_LIBTHAI_SHARED TRUE)
|
||||
sdl_include_directories(PRIVATE SYSTEM $<TARGET_PROPERTY:PkgConfig::PC_LIBTHAI,INTERFACE_INCLUDE_DIRECTORIES>)
|
||||
else()
|
||||
sdl_link_dependency(libthai LIBS PkgConfig::PC_LIBTHAI PKG_CONFIG_PREFIX PC_LIBTHAI PKG_CONFIG_SPECS ${LIBTHAI_PKG_CONFIG_SPEC})
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
macro(WaylandProtocolGen _SCANNER _CODE_MODE _XML _PROTL)
|
||||
set(_WAYLAND_PROT_C_CODE "${CMAKE_CURRENT_BINARY_DIR}/wayland-generated-protocols/${_PROTL}-protocol.c")
|
||||
set(_WAYLAND_PROT_H_CODE "${CMAKE_CURRENT_BINARY_DIR}/wayland-generated-protocols/${_PROTL}-client-protocol.h")
|
||||
|
||||
@@ -218,6 +218,8 @@
|
||||
#cmakedefine HAVE_LIBURING_H 1
|
||||
#cmakedefine HAVE_FRIBIDI_H 1
|
||||
#cmakedefine SDL_FRIBIDI_DYNAMIC @SDL_FRIBIDI_DYNAMIC@
|
||||
#cmakedefine HAVE_LIBTHAI_H 1
|
||||
#cmakedefine SDL_LIBTHAI_DYNAMIC @SDL_LIBTHAI_DYNAMIC@
|
||||
|
||||
#cmakedefine HAVE_DDRAW_H 1
|
||||
#cmakedefine HAVE_DSOUND_H 1
|
||||
|
||||
76
src/core/unix/SDL_libthai.c
Normal file
76
src/core/unix/SDL_libthai.c
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifdef HAVE_LIBTHAI_H
|
||||
|
||||
#include "SDL_libthai.h"
|
||||
|
||||
#ifdef SDL_LIBTHAI_DYNAMIC
|
||||
SDL_ELF_NOTE_DLOPEN(
|
||||
"Thai",
|
||||
"Thai language support",
|
||||
SDL_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED,
|
||||
SDL_LIBTHAI_DYNAMIC
|
||||
);
|
||||
#endif
|
||||
|
||||
|
||||
SDL_LibThai *SDL_LibThai_Create(void)
|
||||
{
|
||||
SDL_LibThai *th;
|
||||
|
||||
th = (SDL_LibThai *)SDL_malloc(sizeof(SDL_LibThai));
|
||||
if (!th) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef SDL_LIBTHAI_DYNAMIC
|
||||
#define SDL_LIBTHAI_LOAD_SYM(a, x, n, t) x = ((t)SDL_LoadFunction(a->lib, n)); if (!x) { SDL_UnloadObject(a->lib); SDL_free(a); return NULL; }
|
||||
|
||||
th->lib = SDL_LoadObject(SDL_LIBTHAI_DYNAMIC);
|
||||
if (!th->lib) {
|
||||
SDL_free(th);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
SDL_LIBTHAI_LOAD_SYM(th, th->make_cells, "th_make_cells", SDL_LibThaiMakeCells);
|
||||
#else
|
||||
th->make_cells = th_make_cells;
|
||||
#endif
|
||||
|
||||
return th;
|
||||
}
|
||||
|
||||
void SDL_LibThai_Destroy(SDL_LibThai *th)
|
||||
{
|
||||
if (!th) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef SDL_LIBTHAI_DYNAMIC
|
||||
SDL_UnloadObject(th->lib);
|
||||
#endif
|
||||
|
||||
SDL_free(th);
|
||||
}
|
||||
|
||||
#endif
|
||||
43
src/core/unix/SDL_libthai.h
Normal file
43
src/core/unix/SDL_libthai.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "SDL_internal.h"
|
||||
|
||||
#ifndef SDL_libthai_h_
|
||||
#define SDL_libthai_h_
|
||||
|
||||
#ifdef HAVE_LIBTHAI_H
|
||||
#include <thai/thcell.h>
|
||||
|
||||
typedef size_t (*SDL_LibThaiMakeCells)(const thchar_t *s, size_t, struct thcell_t cells[], size_t *, int);
|
||||
|
||||
typedef struct SDL_LibThai {
|
||||
SDL_SharedObject *lib;
|
||||
|
||||
SDL_LibThaiMakeCells make_cells;
|
||||
} SDL_LibThai;
|
||||
|
||||
extern SDL_LibThai *SDL_LibThai_Create(void);
|
||||
extern void SDL_LibThai_Destroy(SDL_LibThai *th);
|
||||
|
||||
#endif // HAVE_LIBTHAI_H
|
||||
|
||||
#endif // SDL_libthai_h_
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "SDL_x11toolkit.h"
|
||||
|
||||
#ifndef SDL_FORK_MESSAGEBOX
|
||||
#define SDL_FORK_MESSAGEBOX 1
|
||||
#define SDL_FORK_MESSAGEBOX 0
|
||||
#endif
|
||||
|
||||
#if SDL_FORK_MESSAGEBOX
|
||||
@@ -38,246 +38,181 @@
|
||||
#include <errno.h>
|
||||
#endif
|
||||
|
||||
typedef struct SDL_MessageBoxCallbackDataX11
|
||||
{
|
||||
int *buttonID;
|
||||
SDL_ToolkitWindowX11 *window;
|
||||
} SDL_MessageBoxCallbackDataX11;
|
||||
|
||||
typedef struct SDL_MessageBoxControlsX11
|
||||
typedef struct SDL_MessageBoxX11
|
||||
{
|
||||
SDL_ToolkitWindowX11 *window;
|
||||
SDL_ToolkitControlX11 *icon;
|
||||
SDL_ToolkitControlX11 fake_icon;
|
||||
SDL_ToolkitControlX11 *message;
|
||||
SDL_ToolkitControlX11 **buttons;
|
||||
const SDL_MessageBoxData *messageboxdata;
|
||||
} SDL_MessageBoxControlsX11;
|
||||
int *buttonID;
|
||||
} SDL_MessageBoxX11;
|
||||
|
||||
static void X11_MessageBoxButtonCallback(SDL_ToolkitControlX11 *control, void *data)
|
||||
{
|
||||
SDL_MessageBoxCallbackDataX11 *cbdata;
|
||||
SDL_MessageBoxX11 *cbdata;
|
||||
|
||||
cbdata = (SDL_MessageBoxCallbackDataX11 *)data;
|
||||
cbdata = data;
|
||||
*cbdata->buttonID = X11Toolkit_GetButtonControlData(control)->buttonID;
|
||||
X11Toolkit_SignalWindowClose(cbdata->window);
|
||||
}
|
||||
|
||||
static void X11_PositionMessageBox(SDL_MessageBoxControlsX11 *controls, int *wp, int *hp) {
|
||||
int max_button_w;
|
||||
int max_button_h;
|
||||
int total_button_w;
|
||||
int total_text_and_icon_w;
|
||||
int w;
|
||||
int h;
|
||||
static void X11_PositionMessageBox(SDL_MessageBoxX11 *controls, int *wp, int *hp) {
|
||||
int first_line_width;
|
||||
int first_line_height;
|
||||
int second_line_width;
|
||||
int second_line_height;
|
||||
int max_button_width;
|
||||
int max_button_height;
|
||||
int window_width;
|
||||
int window_height;
|
||||
int i;
|
||||
int t;
|
||||
|
||||
/* Init vars */
|
||||
max_button_w = 50;
|
||||
max_button_h = 0;
|
||||
w = h = 2;
|
||||
i = t = total_button_w = total_text_and_icon_w = 0;
|
||||
max_button_w *= controls->window->iscale;
|
||||
|
||||
/* Positioning and sizing */
|
||||
for (i = 0; i < controls->messageboxdata->numbuttons; i++) {
|
||||
max_button_w = SDL_max(max_button_w, controls->buttons[i]->rect.w);
|
||||
max_button_h = SDL_max(max_button_h, controls->buttons[i]->rect.h);
|
||||
controls->buttons[i]->rect.x = 0;
|
||||
}
|
||||
|
||||
if (controls->icon) {
|
||||
controls->icon->rect.x = controls->icon->rect.y = 0;
|
||||
}
|
||||
|
||||
if (controls->icon) {
|
||||
controls->message->rect.x = (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale) + controls->icon->rect.x + controls->icon->rect.w;
|
||||
controls->message->rect.y = X11Toolkit_GetIconControlCharY(controls->icon);
|
||||
} else {
|
||||
controls->message->rect.x = 0;
|
||||
controls->message->rect.y = -2 * controls->window->iscale;
|
||||
controls->icon = &controls->fake_icon;
|
||||
controls->icon->rect.w = 0;
|
||||
controls->icon->rect.h = 0;
|
||||
controls->icon->rect.x = 0;
|
||||
controls->icon->rect.y = 0;
|
||||
}
|
||||
bool rtl;
|
||||
|
||||
/* window size */
|
||||
window_width = 1;
|
||||
window_height = 1;
|
||||
|
||||
/* rtl */
|
||||
if (controls->messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT) {
|
||||
for (i = controls->messageboxdata->numbuttons; i != -1; i--) {
|
||||
controls->buttons[i]->rect.w = max_button_w;
|
||||
controls->buttons[i]->rect.h = max_button_h;
|
||||
rtl = true;
|
||||
} else if (controls->messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_LEFT_TO_RIGHT) {
|
||||
rtl = false;
|
||||
} else {
|
||||
rtl = controls->window->flip_interface;
|
||||
}
|
||||
|
||||
/* first line */
|
||||
first_line_width = first_line_height = 0;
|
||||
if (controls->icon && controls->message) {
|
||||
controls->icon->rect.y = 0;
|
||||
|
||||
first_line_width = controls->icon->rect.w + SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale + controls->message->rect.w;
|
||||
|
||||
if (!controls->window->flip_interface) {
|
||||
controls->message->rect.x = controls->icon->rect.w + SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale;
|
||||
controls->icon->rect.x = 0;
|
||||
} else {
|
||||
controls->message->rect.x = 0;
|
||||
controls->icon->rect.x = controls->message->rect.w + SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale;;
|
||||
}
|
||||
|
||||
if (controls->message->rect.h > controls->icon->rect.h) {
|
||||
controls->message->rect.y = (controls->icon->rect.h - X11Toolkit_GetLabelControlFirstLineHeight(controls->message))/2;
|
||||
first_line_height = controls->message->rect.y + controls->message->rect.h;
|
||||
} else {
|
||||
controls->message->rect.y = (controls->icon->rect.h - controls->message->rect.h)/2;
|
||||
first_line_height = controls->icon->rect.h;
|
||||
}
|
||||
} else if (!controls->icon && controls->message) {
|
||||
first_line_width = controls->message->rect.w;
|
||||
first_line_height = controls->message->rect.h;
|
||||
controls->message->rect.x = 0;
|
||||
controls->message->rect.y = 0;
|
||||
} else if (controls->icon && !controls->message) {
|
||||
first_line_width = controls->icon->rect.w;
|
||||
first_line_height = controls->icon->rect.h;
|
||||
controls->icon->rect.x = 0;
|
||||
controls->icon->rect.y = 0;
|
||||
}
|
||||
|
||||
/* second line */
|
||||
max_button_width = 50;
|
||||
max_button_height = 0;
|
||||
second_line_width = second_line_height = 0;
|
||||
|
||||
for (i = 0; i < controls->messageboxdata->numbuttons; i++) {
|
||||
max_button_width = SDL_max(max_button_width, controls->buttons[i]->rect.w);
|
||||
max_button_height = SDL_max(max_button_height, controls->buttons[i]->rect.h);
|
||||
controls->buttons[i]->rect.x = 0;
|
||||
controls->buttons[i]->rect.y = 0;
|
||||
}
|
||||
|
||||
if (rtl) {
|
||||
for (i = (controls->messageboxdata->numbuttons - 1); i != -1; i--) {
|
||||
controls->buttons[i]->rect.w = max_button_width;
|
||||
controls->buttons[i]->rect.h = max_button_height;
|
||||
X11Toolkit_NotifyControlOfSizeChange(controls->buttons[i]);
|
||||
|
||||
if (controls->icon->rect.h > controls->message->rect.h) {
|
||||
controls->buttons[i]->rect.y = controls->icon->rect.h + (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 *controls-> window->iscale);
|
||||
if (first_line_height) {
|
||||
controls->buttons[i]->rect.y = first_line_height + SDL_TOOLKIT_X11_ELEMENT_PADDING_4 * controls->window->iscale;
|
||||
second_line_height = max_button_height + SDL_TOOLKIT_X11_ELEMENT_PADDING_4 * controls->window->iscale;
|
||||
} else {
|
||||
controls->buttons[i]->rect.y = controls->message->rect.h + (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale);
|
||||
second_line_height = max_button_height;
|
||||
}
|
||||
|
||||
if (i) {
|
||||
controls->buttons[i]->rect.x = controls->buttons[i-1]->rect.x + controls->buttons[i-1]->rect.w + (SDL_TOOLKIT_X11_ELEMENT_PADDING_3 * controls->window->iscale);
|
||||
|
||||
if ((i + 1) < controls->messageboxdata->numbuttons) {
|
||||
controls->buttons[i]->rect.x = controls->buttons[i + 1]->rect.x + controls->buttons[i + 1]->rect.w + (SDL_TOOLKIT_X11_ELEMENT_PADDING_3 * controls->window->iscale);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < controls->messageboxdata->numbuttons; i++) {
|
||||
controls->buttons[i]->rect.w = max_button_w;
|
||||
controls->buttons[i]->rect.h = max_button_h;
|
||||
controls->buttons[i]->rect.w = max_button_width;
|
||||
controls->buttons[i]->rect.h = max_button_height;
|
||||
X11Toolkit_NotifyControlOfSizeChange(controls->buttons[i]);
|
||||
|
||||
if (controls->icon->rect.h > controls->message->rect.h) {
|
||||
controls->buttons[i]->rect.y = controls->icon->rect.h + (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale);
|
||||
if (first_line_height) {
|
||||
controls->buttons[i]->rect.y = first_line_height + SDL_TOOLKIT_X11_ELEMENT_PADDING_4 * controls->window->iscale;
|
||||
second_line_height = max_button_height + SDL_TOOLKIT_X11_ELEMENT_PADDING_4 * controls->window->iscale;
|
||||
} else {
|
||||
controls->buttons[i]->rect.y = controls->message->rect.h + (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale);
|
||||
second_line_height = max_button_height;
|
||||
}
|
||||
|
||||
|
||||
if (i) {
|
||||
controls->buttons[i]->rect.x = controls->buttons[i-1]->rect.x + controls->buttons[i-1]->rect.w + (SDL_TOOLKIT_X11_ELEMENT_PADDING_3 * controls->window->iscale);
|
||||
}
|
||||
}
|
||||
}
|
||||
total_button_w = controls->buttons[controls->messageboxdata->numbuttons-1]->rect.x + controls->buttons[controls->messageboxdata->numbuttons-1]->rect.w;
|
||||
total_text_and_icon_w = controls->message->rect.x + controls->message->rect.w;
|
||||
if (total_button_w > total_text_and_icon_w) {
|
||||
w = total_button_w;
|
||||
} else {
|
||||
w = total_text_and_icon_w;
|
||||
}
|
||||
w += (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale) * 2;
|
||||
if (controls->message->rect.h > controls->icon->rect.h) {
|
||||
h = controls->message->rect.h;
|
||||
} else {
|
||||
h = controls->icon->rect.h;
|
||||
}
|
||||
h += max_button_h + (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale) * 3;
|
||||
t = (w - total_text_and_icon_w) / 2;
|
||||
controls->icon->rect.x += t;
|
||||
controls->message->rect.x += t;
|
||||
controls->icon->rect.y += (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale);
|
||||
controls->message->rect.y += (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale);
|
||||
t = (w - total_button_w) / 2;
|
||||
for (i = 0; i < controls->messageboxdata->numbuttons; i++) {
|
||||
controls->buttons[i]->rect.x += t;
|
||||
controls->buttons[i]->rect.y += (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale);
|
||||
}
|
||||
if (!controls->messageboxdata->message) {
|
||||
controls->icon->rect.x = (w - controls->icon->rect.w)/2;
|
||||
|
||||
if (controls->messageboxdata->numbuttons) {
|
||||
if (rtl) {
|
||||
second_line_width = controls->buttons[0]->rect.x + controls->buttons[0]->rect.w;
|
||||
} else {
|
||||
second_line_width = controls->buttons[controls->messageboxdata->numbuttons - 1]->rect.x + controls->buttons[controls->messageboxdata->numbuttons - 1]->rect.w;
|
||||
}
|
||||
}
|
||||
|
||||
*wp = w;
|
||||
*hp = h;
|
||||
}
|
||||
|
||||
static void X11_PositionMessageBoxFlipped(SDL_MessageBoxControlsX11 *controls, int *wp, int *hp)
|
||||
{
|
||||
int max_button_w;
|
||||
int max_button_h;
|
||||
int total_button_w;
|
||||
int total_text_and_icon_w;
|
||||
int w;
|
||||
int h;
|
||||
int i;
|
||||
int t;
|
||||
|
||||
/* Init vars */
|
||||
max_button_w = 50;
|
||||
max_button_h = 0;
|
||||
w = h = 2;
|
||||
i = t = total_button_w = total_text_and_icon_w = 0;
|
||||
max_button_w *= controls->window->iscale;
|
||||
|
||||
/* Positioning and sizing */
|
||||
for (i = 0; i < controls->messageboxdata->numbuttons; i++) {
|
||||
max_button_w = SDL_max(max_button_w, controls->buttons[i]->rect.w);
|
||||
max_button_h = SDL_max(max_button_h, controls->buttons[i]->rect.h);
|
||||
controls->buttons[i]->rect.x = 0;
|
||||
}
|
||||
|
||||
if (controls->icon) {
|
||||
controls->icon->rect.y = 0;
|
||||
}
|
||||
|
||||
if (controls->icon) {
|
||||
controls->message->rect.x = 0;
|
||||
controls->message->rect.y = X11Toolkit_GetIconControlCharY(controls->icon);
|
||||
controls->icon->rect.x = (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale) + controls->message->rect.w + controls->message->rect.x;
|
||||
} else {
|
||||
controls->message->rect.x = 0;
|
||||
controls->message->rect.y = -2 * controls->window->iscale;
|
||||
controls->icon = &controls->fake_icon;
|
||||
controls->icon->rect.w = 0;
|
||||
controls->icon->rect.h = 0;
|
||||
controls->icon->rect.x = 0;
|
||||
controls->icon->rect.y = 0;
|
||||
}
|
||||
if (controls->messageboxdata->flags & SDL_MESSAGEBOX_BUTTONS_RIGHT_TO_LEFT) {
|
||||
for (i = controls->messageboxdata->numbuttons; i != -1; i--) {
|
||||
controls->buttons[i]->rect.w = max_button_w;
|
||||
controls->buttons[i]->rect.h = max_button_h;
|
||||
X11Toolkit_NotifyControlOfSizeChange(controls->buttons[i]);
|
||||
|
||||
if (controls->icon->rect.h > controls->message->rect.h) {
|
||||
controls->buttons[i]->rect.y = controls->icon->rect.h + (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 *controls-> window->iscale);
|
||||
} else {
|
||||
controls->buttons[i]->rect.y = controls->message->rect.h + (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale);
|
||||
}
|
||||
|
||||
if (i) {
|
||||
controls->buttons[i]->rect.x = controls->buttons[i-1]->rect.x + controls->buttons[i-1]->rect.w + (SDL_TOOLKIT_X11_ELEMENT_PADDING_3 * controls->window->iscale);
|
||||
}
|
||||
/* center lines */
|
||||
if (second_line_width > first_line_width) {
|
||||
int pad;
|
||||
|
||||
pad = (second_line_width - first_line_width)/2;
|
||||
if (controls->message) {
|
||||
controls->message->rect.x += pad;
|
||||
}
|
||||
if (controls->icon) {
|
||||
controls->icon->rect.x += pad;
|
||||
}
|
||||
} else {
|
||||
int pad;
|
||||
|
||||
pad = (first_line_width - second_line_width)/2;
|
||||
for (i = 0; i < controls->messageboxdata->numbuttons; i++) {
|
||||
controls->buttons[i]->rect.w = max_button_w;
|
||||
controls->buttons[i]->rect.h = max_button_h;
|
||||
X11Toolkit_NotifyControlOfSizeChange(controls->buttons[i]);
|
||||
|
||||
if (controls->icon->rect.h > controls->message->rect.h) {
|
||||
controls->buttons[i]->rect.y = controls->icon->rect.h + (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale);
|
||||
} else {
|
||||
controls->buttons[i]->rect.y = controls->message->rect.h + (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale);
|
||||
}
|
||||
|
||||
if (i) {
|
||||
controls->buttons[i]->rect.x = controls->buttons[i-1]->rect.x + controls->buttons[i-1]->rect.w + (SDL_TOOLKIT_X11_ELEMENT_PADDING_3 * controls->window->iscale);
|
||||
}
|
||||
controls->buttons[i]->rect.x += pad;
|
||||
}
|
||||
}
|
||||
total_button_w = controls->buttons[controls->messageboxdata->numbuttons-1]->rect.x + controls->buttons[controls->messageboxdata->numbuttons-1]->rect.w;
|
||||
total_text_and_icon_w = controls->message->rect.w + controls->icon->rect.w + (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale);
|
||||
if (total_button_w > total_text_and_icon_w) {
|
||||
w = total_button_w;
|
||||
} else {
|
||||
w = total_text_and_icon_w;
|
||||
|
||||
/* window size and final padding */
|
||||
window_width = SDL_max(first_line_width, second_line_width) + SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * 2 * controls->window->iscale;
|
||||
window_height = first_line_height + second_line_height + SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * 2 * controls->window->iscale;
|
||||
*wp = window_width;
|
||||
*hp = window_height;
|
||||
if (controls->message) {
|
||||
controls->message->rect.x += SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale;
|
||||
controls->message->rect.y += SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale;
|
||||
}
|
||||
w += (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale) * 2;
|
||||
if (controls->message->rect.h > controls->icon->rect.h) {
|
||||
h = controls->message->rect.h;
|
||||
} else {
|
||||
h = controls->icon->rect.h;
|
||||
if (controls->icon) {
|
||||
controls->icon->rect.x += SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale;
|
||||
controls->icon->rect.y += SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale;
|
||||
}
|
||||
h += max_button_h + (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale) * 3;
|
||||
t = (w - total_text_and_icon_w) / 2;
|
||||
controls->icon->rect.x += t;
|
||||
controls->message->rect.x += t;
|
||||
controls->icon->rect.y += (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale);
|
||||
controls->message->rect.y += (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale);
|
||||
t = (w - total_button_w) / 2;
|
||||
for (i = 0; i < controls->messageboxdata->numbuttons; i++) {
|
||||
controls->buttons[i]->rect.x += t;
|
||||
controls->buttons[i]->rect.y += (SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale);
|
||||
controls->buttons[i]->rect.x += SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale;
|
||||
controls->buttons[i]->rect.y += SDL_TOOLKIT_X11_ELEMENT_PADDING_2 * controls->window->iscale;
|
||||
}
|
||||
if (!controls->messageboxdata->message) {
|
||||
controls->icon->rect.x = (w - controls->icon->rect.w)/2;
|
||||
}
|
||||
|
||||
*wp = w;
|
||||
*hp = h;
|
||||
}
|
||||
|
||||
|
||||
static void X11_OnMessageBoxScaleChange(SDL_ToolkitWindowX11 *window, void *data) {
|
||||
SDL_MessageBoxControlsX11 *controls;
|
||||
SDL_MessageBoxX11 *controls;
|
||||
int w;
|
||||
int h;
|
||||
|
||||
@@ -290,8 +225,7 @@ static bool X11_ShowMessageBoxImpl(const SDL_MessageBoxData *messageboxdata, int
|
||||
{
|
||||
SDL_VideoDevice *video = SDL_GetVideoDevice();
|
||||
SDL_Window *parent_window = NULL;
|
||||
SDL_MessageBoxControlsX11 controls;
|
||||
SDL_MessageBoxCallbackDataX11 data;
|
||||
SDL_MessageBoxX11 controls;
|
||||
const SDL_MessageBoxColor *colorhints;
|
||||
int i;
|
||||
int w;
|
||||
@@ -323,22 +257,17 @@ static bool X11_ShowMessageBoxImpl(const SDL_MessageBoxData *messageboxdata, int
|
||||
}
|
||||
|
||||
/* Create controls */
|
||||
controls.buttonID = buttonID;
|
||||
controls.buttons = SDL_calloc(messageboxdata->numbuttons, sizeof(SDL_ToolkitControlX11 *));
|
||||
controls.icon = X11Toolkit_CreateIconControl(controls.window, messageboxdata->flags);
|
||||
controls.message = X11Toolkit_CreateLabelControl(controls.window, (char *)messageboxdata->message);
|
||||
data.buttonID = buttonID;
|
||||
data.window = controls.window;
|
||||
for (i = 0; i < messageboxdata->numbuttons; i++) {
|
||||
controls.buttons[i] = X11Toolkit_CreateButtonControl(controls.window, &messageboxdata->buttons[i]);
|
||||
X11Toolkit_RegisterCallbackForButtonControl(controls.buttons[i], &data, X11_MessageBoxButtonCallback);
|
||||
X11Toolkit_RegisterCallbackForButtonControl(controls.buttons[i], &controls, X11_MessageBoxButtonCallback);
|
||||
}
|
||||
|
||||
/* Positioning */
|
||||
if (data.window->flip_interface) {
|
||||
X11_PositionMessageBoxFlipped(&controls, &w, &h);
|
||||
} else {
|
||||
X11_PositionMessageBox(&controls, &w, &h);
|
||||
}
|
||||
X11_PositionMessageBox(&controls, &w, &h);
|
||||
|
||||
/* Actually create window, do event loop, cleanup */
|
||||
X11Toolkit_CreateWindowRes(controls.window, w, h, 0, 0, (char *)messageboxdata->title);
|
||||
|
||||
@@ -56,6 +56,7 @@ SDL_X11_SYM(int,XDeleteProperty,(Display* a,Window b,Atom c))
|
||||
SDL_X11_SYM(int,XDestroyWindow,(Display* a,Window b))
|
||||
SDL_X11_SYM(int,XDisplayKeycodes,(Display* a,int* b,int* c))
|
||||
SDL_X11_SYM(int,XDrawRectangle,(Display* a,Drawable b,GC c,int d,int e,unsigned int f,unsigned int g))
|
||||
SDL_X11_SYM(int,XFontsOfFontSet,(XFontSet a,XFontStruct ***b,char ***c))
|
||||
SDL_X11_SYM(int,XFillArc,(Display* a,Drawable b,GC c,int d,int e,unsigned int f,unsigned int g, int h, int i))
|
||||
SDL_X11_SYM(char*,XDisplayName,(_Xconst char* a))
|
||||
SDL_X11_SYM(int,XDrawString,(Display* a,Drawable b,GC c,int d,int e,_Xconst char* f,int g))
|
||||
|
||||
@@ -42,6 +42,35 @@
|
||||
#define SDL_SET_LOCALE 1
|
||||
#define SDL_GRAB 1
|
||||
|
||||
typedef enum SDL_ToolkitTextTypeX11
|
||||
{
|
||||
SDL_TOOLKIT_TEXT_TYPE_X11_GENERIC,
|
||||
SDL_TOOLKIT_TEXT_TYPE_X11_THAI
|
||||
} SDL_ToolkitTextTypeX11;
|
||||
|
||||
#ifdef HAVE_LIBTHAI_H
|
||||
typedef struct SDL_ToolkitThaiOverlayX11
|
||||
{
|
||||
bool top;
|
||||
char *str;
|
||||
size_t sz;
|
||||
SDL_Rect rect;
|
||||
} SDL_ToolkitThaiOverlayX11;
|
||||
#endif
|
||||
|
||||
typedef struct SDL_ToolkitTextElementX11
|
||||
{
|
||||
SDL_ToolkitTextTypeX11 type;
|
||||
char *str;
|
||||
size_t sz;
|
||||
SDL_Rect rect;
|
||||
int font_h;
|
||||
void (*str_free)(void *);
|
||||
#ifdef HAVE_LIBTHAI_H
|
||||
SDL_ListNode *thai_overlays;
|
||||
#endif
|
||||
} SDL_ToolkitTextElementX11;
|
||||
|
||||
typedef struct SDL_ToolkitIconControlX11
|
||||
{
|
||||
SDL_ToolkitControlX11 parent;
|
||||
@@ -75,25 +104,28 @@ typedef struct SDL_ToolkitButtonControlX11
|
||||
const SDL_MessageBoxButtonData *data;
|
||||
|
||||
/* Text */
|
||||
SDL_ListNode *text;
|
||||
SDL_Rect text_rect;
|
||||
int text_a;
|
||||
int text_d;
|
||||
int str_sz;
|
||||
#ifdef HAVE_FRIBIDI_H
|
||||
char *text;
|
||||
bool free_text;
|
||||
#endif
|
||||
|
||||
|
||||
/* Callback */
|
||||
void *cb_data;
|
||||
void (*cb)(struct SDL_ToolkitControlX11 *, void *);
|
||||
} SDL_ToolkitButtonControlX11;
|
||||
|
||||
typedef struct SDL_ToolkitLabelControlLineX11
|
||||
{
|
||||
SDL_ListNode *text;
|
||||
SDL_Rect rect;
|
||||
#ifdef HAVE_FRIBIDI_H
|
||||
FriBidiParType par;
|
||||
#endif
|
||||
} SDL_ToolkitLabelControlLineX11;
|
||||
|
||||
typedef struct SDL_ToolkitLabelControlX11
|
||||
{
|
||||
SDL_ToolkitControlX11 parent;
|
||||
|
||||
char **lines;
|
||||
/* char **lines;
|
||||
int *y;
|
||||
size_t *szs;
|
||||
size_t sz;
|
||||
@@ -102,7 +134,9 @@ typedef struct SDL_ToolkitLabelControlX11
|
||||
int *w;
|
||||
bool *free_lines;
|
||||
FriBidiParType *par_types;
|
||||
#endif
|
||||
#endif*/
|
||||
SDL_ToolkitLabelControlLineX11 *lines;
|
||||
size_t sz;
|
||||
} SDL_ToolkitLabelControlX11;
|
||||
|
||||
typedef struct SDL_ToolkitMenuBarControlX11
|
||||
@@ -258,7 +292,9 @@ static void X11Toolkit_InitWindowPixmap(SDL_ToolkitWindowX11 *data) {
|
||||
}
|
||||
|
||||
static void X11Toolkit_InitWindowFonts(SDL_ToolkitWindowX11 *window)
|
||||
{
|
||||
{
|
||||
window->thai_encoding = SDL_TOOLKIT_THAI_ENCODING_X11_NONE;
|
||||
window->thai_font = SDL_TOOLKIT_THAI_FONT_X11_CELL;
|
||||
#ifdef X_HAVE_UTF8_STRING
|
||||
window->utf8 = true;
|
||||
window->font_set = NULL;
|
||||
@@ -301,9 +337,56 @@ static void X11Toolkit_InitWindowFonts(SDL_ToolkitWindowX11 *window)
|
||||
if (!window->font_set) {
|
||||
goto load_font_traditional;
|
||||
} else {
|
||||
XFontStruct **font_structs;
|
||||
char **font_names;
|
||||
int font_sz;
|
||||
int i;
|
||||
|
||||
#ifdef HAVE_FRIBIDI_H
|
||||
window->do_shaping = !X11_XContextDependentDrawing(window->font_set);
|
||||
#endif
|
||||
/* TODO: What to do the XFontSet happens to have more than one Thai font? */
|
||||
font_sz = X11_XFontsOfFontSet(window->font_set, &font_structs, &font_names);
|
||||
for (i = 0; i < font_sz; i++) {
|
||||
SDL_ToolkitThaiEncodingX11 thai_encoding;
|
||||
|
||||
thai_encoding = SDL_TOOLKIT_THAI_ENCODING_X11_NONE;
|
||||
if (SDL_strstr(font_names[i], "tis620-0")) {
|
||||
thai_encoding = SDL_TOOLKIT_THAI_ENCODING_X11_TIS;
|
||||
} else if (SDL_strstr(font_names[i], "tis620-1")) {
|
||||
thai_encoding = SDL_TOOLKIT_THAI_ENCODING_X11_TIS_MAC;
|
||||
} else if (SDL_strstr(font_names[i], "tis620-2")) {
|
||||
thai_encoding = SDL_TOOLKIT_THAI_ENCODING_X11_TIS_WIN;
|
||||
} else if (SDL_strstr(font_names[i], "iso8859-11")) {
|
||||
thai_encoding = SDL_TOOLKIT_THAI_ENCODING_X11_8859;
|
||||
} else if (SDL_strstr(font_names[i], "iso10646-1")) {
|
||||
thai_encoding = SDL_TOOLKIT_THAI_ENCODING_X11_UNICODE;
|
||||
}
|
||||
|
||||
/* TODO: Set encoding to none if the font does not actually have any Thai codepoints */
|
||||
if (thai_encoding != SDL_TOOLKIT_THAI_ENCODING_X11_NONE) {
|
||||
XFontStruct *font_struct;
|
||||
|
||||
/* We have to load the font again because the font_struct supplied by FontsOfFontSet does not have the per_char member set */
|
||||
font_struct = X11_XLoadQueryFont(window->display, font_names[i]);
|
||||
if (font_struct) {
|
||||
if (font_struct->per_char) {
|
||||
int glyphs_sz;
|
||||
int j;
|
||||
|
||||
glyphs_sz = (font_struct->max_char_or_byte2 - font_struct->min_char_or_byte2 + 1) * (font_struct->max_byte1 - font_struct->min_byte1 + 1);
|
||||
for (j = 0; j < glyphs_sz; j++) {
|
||||
if (font_struct->per_char[j].lbearing < 0) {
|
||||
window->thai_font = SDL_TOOLKIT_THAI_FONT_X11_OFFSET;
|
||||
}
|
||||
}
|
||||
}
|
||||
X11_XFreeFont(window->display, font_struct);
|
||||
}
|
||||
}
|
||||
|
||||
window->thai_encoding = thai_encoding;
|
||||
}
|
||||
}
|
||||
} else
|
||||
#endif
|
||||
@@ -445,16 +528,18 @@ static void X11Toolkit_SettingsNotify(const char *name, XSettingsAction action,
|
||||
}
|
||||
}
|
||||
|
||||
static void X11Toolkit_GetTextWidthHeightForFont(XFontStruct *font, const char *str, int nbytes, int *pwidth, int *pheight, int *ascent)
|
||||
static void X11Toolkit_GetTextWidthHeightForFont(XFontStruct *font, const char *str, int nbytes, int *pwidth, int *pheight, int *ascent, int *font_height)
|
||||
{
|
||||
XCharStruct text_structure;
|
||||
int font_direction, font_ascent, font_descent;
|
||||
X11_XTextExtents(font, str, nbytes,
|
||||
&font_direction, &font_ascent, &font_descent,
|
||||
&text_structure);
|
||||
|
||||
X11_XTextExtents(font, str, nbytes, &font_direction, &font_ascent, &font_descent, &text_structure);
|
||||
*pwidth = text_structure.width;
|
||||
*pheight = text_structure.ascent + text_structure.descent;
|
||||
*ascent = text_structure.ascent;
|
||||
if (font_height) {
|
||||
*font_height = font_ascent + font_descent;
|
||||
}
|
||||
}
|
||||
|
||||
static void X11Toolkit_GetTextWidthHeight(SDL_ToolkitWindowX11 *data, const char *str, int nbytes, int *pwidth, int *pheight, int *ascent, int *descent, int *font_height)
|
||||
@@ -494,6 +579,335 @@ static void X11Toolkit_GetTextWidthHeight(SDL_ToolkitWindowX11 *data, const char
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef HAVE_FRIBIDI_H
|
||||
SDL_ListNode *X11Toolkit_MakeTextElements(SDL_ToolkitWindowX11 *data, char *txt, size_t sz, FriBidiParType *par)
|
||||
#else
|
||||
SDL_ListNode *X11Toolkit_MakeTextElements(SDL_ToolkitWindowX11 *data, char *txt, size_t sz)
|
||||
#endif
|
||||
{
|
||||
SDL_ListNode *list;
|
||||
char *str;
|
||||
char *buffer;
|
||||
Uint32 cp;
|
||||
bool thai;
|
||||
bool free_txt;
|
||||
|
||||
free_txt = false;
|
||||
list = NULL;
|
||||
thai = 0;
|
||||
str = txt;
|
||||
buffer = SDL_malloc(1);
|
||||
buffer[0] = 0;
|
||||
|
||||
#ifdef HAVE_FRIBIDI_H
|
||||
if (par) {
|
||||
*par = FRIBIDI_PAR_LTR;
|
||||
}
|
||||
if (data->fribidi) {
|
||||
char *fstr;
|
||||
|
||||
fstr = SDL_FriBidi_Process(data->fribidi, str, sz, data->do_shaping, par);
|
||||
if (fstr) {
|
||||
txt = fstr;
|
||||
str = fstr;
|
||||
sz = SDL_strlen(str);
|
||||
free_txt = true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
while (1) {
|
||||
char *new;
|
||||
char utf8[5];
|
||||
size_t csz;
|
||||
bool cond;
|
||||
|
||||
SDL_memset(utf8, 0, 5);
|
||||
cp = SDL_StepUTF8((const char **)&str, &sz);
|
||||
cond = (0xe00 <= cp && cp <= 0xe7f) ? true : false;
|
||||
if (cp == 0 || cond == (thai ? false : true)) {
|
||||
SDL_ToolkitTextElementX11 *element;
|
||||
|
||||
element = SDL_malloc(sizeof(SDL_ToolkitTextElementX11));
|
||||
if (thai) {
|
||||
element->type = SDL_TOOLKIT_TEXT_TYPE_X11_THAI;
|
||||
} else {
|
||||
element->type = SDL_TOOLKIT_TEXT_TYPE_X11_GENERIC;
|
||||
}
|
||||
element->str = SDL_strdup(buffer);
|
||||
element->sz = SDL_strlen(buffer);
|
||||
element->str_free = SDL_free;
|
||||
|
||||
SDL_ListAdd(&list, element);
|
||||
|
||||
SDL_free(buffer);
|
||||
buffer = SDL_malloc(1);
|
||||
buffer[0] = 0;
|
||||
thai = thai ? false : true;
|
||||
}
|
||||
|
||||
if (!cp) {
|
||||
break;
|
||||
}
|
||||
|
||||
SDL_UCS4ToUTF8(cp, utf8);
|
||||
csz = SDL_strlen(buffer) + SDL_strlen(utf8) + 1;
|
||||
new = SDL_malloc(csz);
|
||||
SDL_strlcpy(new, buffer, csz);
|
||||
SDL_strlcat(new, utf8, csz);
|
||||
SDL_free(buffer);
|
||||
buffer = new;
|
||||
}
|
||||
|
||||
SDL_free(buffer);
|
||||
if (free_txt) {
|
||||
SDL_free(txt);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
void X11Toolkit_ShapeTextElements(SDL_ToolkitWindowX11 *data, SDL_ListNode *list)
|
||||
{
|
||||
SDL_ListNode *cursor;
|
||||
SDL_ToolkitTextElementX11 *prev;
|
||||
int temp;
|
||||
|
||||
/* Shape and calculate bounding box */
|
||||
cursor = list;
|
||||
while (cursor) {
|
||||
SDL_ToolkitTextElementX11 *element;
|
||||
|
||||
element = cursor->entry;
|
||||
#ifdef HAVE_LIBTHAI_H
|
||||
element->thai_overlays = NULL;
|
||||
#endif
|
||||
if (element->type == SDL_TOOLKIT_TEXT_TYPE_X11_THAI) {
|
||||
if (data->thai_font == SDL_TOOLKIT_THAI_FONT_X11_OFFSET) {
|
||||
X11Toolkit_GetTextWidthHeight(data, element->str, element->sz, &element->rect.w, &element->rect.h, &element->rect.y, &temp, NULL);
|
||||
} else {
|
||||
#ifdef HAVE_LIBTHAI_H
|
||||
if (data->th) {
|
||||
struct thcell_t *cells;
|
||||
char *tis_str;
|
||||
char *base_tis_str;
|
||||
size_t cells_sz;
|
||||
size_t base_tis_str_sz;
|
||||
size_t tis_str_sz;
|
||||
|
||||
tis_str = SDL_iconv_string("TIS-620", "UTF-8", element->str, element->sz);
|
||||
cells_sz = tis_str_sz = SDL_strlen(tis_str);
|
||||
|
||||
cells = SDL_calloc(cells_sz, sizeof(struct thcell_t));
|
||||
data->th->make_cells((const thchar_t *)tis_str, tis_str_sz, cells, &cells_sz, 0);
|
||||
|
||||
base_tis_str_sz = cells_sz;
|
||||
base_tis_str = SDL_malloc(base_tis_str_sz + 1);
|
||||
for (temp = 0; temp < cells_sz; temp++) {
|
||||
base_tis_str[temp] = cells[temp].base;
|
||||
|
||||
if (cells[temp].hilo) {
|
||||
SDL_ToolkitThaiOverlayX11 *overlay;
|
||||
char *pre;
|
||||
int temp2;
|
||||
|
||||
overlay = SDL_malloc(sizeof(SDL_ToolkitThaiOverlayX11));
|
||||
pre = SDL_iconv_string("UTF-8", "TIS-620", base_tis_str, temp);
|
||||
overlay->str = SDL_iconv_string("UTF-8", "TIS-620", (const char *)&cells[temp].hilo, 1);
|
||||
overlay->sz = SDL_strlen(overlay->str);
|
||||
overlay->top = false;
|
||||
X11Toolkit_GetTextWidthHeight(data, pre, SDL_strlen(pre), &overlay->rect.x, &temp2, &temp2, &temp2, NULL);
|
||||
X11Toolkit_GetTextWidthHeight(data, overlay->str, overlay->sz, &overlay->rect.w, &overlay->rect.h, &overlay->rect.y, &temp2, NULL);
|
||||
SDL_ListAdd(&element->thai_overlays, overlay);
|
||||
SDL_free(pre);
|
||||
}
|
||||
|
||||
if (cells[temp].top) {
|
||||
SDL_ToolkitThaiOverlayX11 *overlay;
|
||||
char *pre;
|
||||
int temp2;
|
||||
|
||||
overlay = SDL_malloc(sizeof(SDL_ToolkitThaiOverlayX11));
|
||||
pre = SDL_iconv_string("UTF-8", "TIS-620", base_tis_str, temp);
|
||||
overlay->str = SDL_iconv_string("UTF-8", "TIS-620", (const char *)&cells[temp].top, 1);
|
||||
overlay->sz = SDL_strlen(overlay->str);
|
||||
overlay->top = true;
|
||||
X11Toolkit_GetTextWidthHeight(data, pre, SDL_strlen(pre), &overlay->rect.x, &temp2, &temp2, &temp2, NULL);
|
||||
X11Toolkit_GetTextWidthHeight(data, overlay->str, overlay->sz, &overlay->rect.w, &overlay->rect.h, &overlay->rect.y, &temp2, NULL);
|
||||
SDL_ListAdd(&element->thai_overlays, overlay);
|
||||
SDL_free(pre);
|
||||
}
|
||||
}
|
||||
base_tis_str[base_tis_str_sz] = '\0';
|
||||
|
||||
element->str_free(element->str);
|
||||
element->str = SDL_iconv_string("UTF-8", "TIS-620", base_tis_str, base_tis_str_sz);
|
||||
element->sz = SDL_strlen(element->str);
|
||||
X11Toolkit_GetTextWidthHeight(data, element->str, element->sz, &element->rect.w, &element->rect.h, &element->rect.y, &temp, &element->font_h);
|
||||
|
||||
SDL_free(tis_str);
|
||||
SDL_free(cells);
|
||||
SDL_free(base_tis_str);
|
||||
}
|
||||
#else
|
||||
X11Toolkit_GetTextWidthHeight(data, element->str, element->sz, &element->rect.w, &element->rect.h, &element->rect.y, &temp, &element->font_h);
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
X11Toolkit_GetTextWidthHeight(data, element->str, element->sz, &element->rect.w, &element->rect.h, &element->rect.y, &temp, &element->font_h);
|
||||
}
|
||||
|
||||
cursor = cursor->next;
|
||||
}
|
||||
|
||||
/* Add offsets */
|
||||
prev = NULL;
|
||||
cursor = list;
|
||||
while (cursor) {
|
||||
SDL_ToolkitTextElementX11 *element;
|
||||
|
||||
element = cursor->entry;
|
||||
if (prev) {
|
||||
element->rect.x = prev->rect.x + prev->rect.w;
|
||||
} else {
|
||||
element->rect.x = 0;
|
||||
}
|
||||
|
||||
prev = element;
|
||||
cursor = cursor->next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void X11Toolkit_DrawTextElements(SDL_ToolkitWindowX11 *data, SDL_ListNode *list, int x, int y)
|
||||
{
|
||||
SDL_ListNode *cursor;
|
||||
|
||||
cursor = list;
|
||||
|
||||
while (cursor) {
|
||||
SDL_ToolkitTextElementX11 *element;
|
||||
|
||||
element = cursor->entry;
|
||||
if (element->type == SDL_TOOLKIT_TEXT_TYPE_X11_THAI) {
|
||||
if (data->thai_font == SDL_TOOLKIT_THAI_FONT_X11_OFFSET) {
|
||||
#ifdef X_HAVE_UTF8_STRING
|
||||
if (data->utf8) {
|
||||
X11_Xutf8DrawString(data->display, data->drawable, data->font_set, data->ctx, x + element->rect.x, y + element->rect.y, element->str, element->sz);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
X11_XDrawString(data->display, data->drawable, data->ctx, x + element->rect.x, y + element->rect.y, element->str, element->sz);
|
||||
}
|
||||
} else {
|
||||
#ifdef HAVE_LIBTHAI_H
|
||||
SDL_ListNode *overlay_cursor;
|
||||
|
||||
/* Draw the base string */
|
||||
#ifdef X_HAVE_UTF8_STRING
|
||||
if (data->utf8) {
|
||||
X11_Xutf8DrawString(data->display, data->drawable, data->font_set, data->ctx, x + element->rect.x, y + element->rect.y, element->str, element->sz);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
X11_XDrawString(data->display, data->drawable, data->ctx, x + element->rect.x, y + element->rect.y, element->str, element->sz);
|
||||
}
|
||||
|
||||
/* Draw overlays */
|
||||
overlay_cursor = element->thai_overlays;
|
||||
while (overlay_cursor) {
|
||||
SDL_ToolkitThaiOverlayX11 *overlay;
|
||||
|
||||
overlay = overlay_cursor->entry;
|
||||
#ifdef X_HAVE_UTF8_STRING
|
||||
if (data->utf8) {
|
||||
X11_Xutf8DrawString(data->display, data->drawable, data->font_set, data->ctx, x + element->rect.x + overlay->rect.x, y + overlay->rect.y, overlay->str, overlay->sz);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
X11_XDrawString(data->display, data->drawable, data->ctx, x + element->rect.x + overlay->rect.x, y + element->rect.y + overlay->rect.y, overlay->str, overlay->sz);
|
||||
}
|
||||
|
||||
overlay_cursor = overlay_cursor->next;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
} else {
|
||||
#ifdef X_HAVE_UTF8_STRING
|
||||
if (data->utf8) {
|
||||
X11_Xutf8DrawString(data->display, data->drawable, data->font_set, data->ctx, x + element->rect.x, y + element->rect.y, element->str, element->sz);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
X11_XDrawString(data->display, data->drawable, data->ctx, x + element->rect.x, y + element->rect.y, element->str, element->sz);
|
||||
}
|
||||
}
|
||||
|
||||
cursor = cursor->next;
|
||||
}
|
||||
}
|
||||
|
||||
int X11Toolkit_GetTextElementsRect(SDL_ListNode *list, SDL_Rect *out)
|
||||
{
|
||||
SDL_ListNode *cursor;
|
||||
int ret;
|
||||
|
||||
ret = 0;
|
||||
out->x = out->y = 0;
|
||||
out->w = out->h = 0;
|
||||
cursor = list;
|
||||
while (cursor) {
|
||||
SDL_ToolkitTextElementX11 *element;
|
||||
|
||||
element = cursor->entry;
|
||||
|
||||
out->w += element->rect.w;
|
||||
out->h = SDL_max(out->h, element->rect.h);
|
||||
ret = SDL_max(ret, element->font_h);
|
||||
|
||||
cursor = cursor->next;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void X11Toolkit_FreeTextElementsListContents(SDL_ListNode *list)
|
||||
{
|
||||
SDL_ListNode *cursor;
|
||||
|
||||
cursor = list;
|
||||
while (cursor) {
|
||||
SDL_ToolkitTextElementX11 *element;
|
||||
#ifdef HAVE_LIBTHAI_H
|
||||
SDL_ListNode *overlay_cursor;
|
||||
#endif
|
||||
|
||||
element = cursor->entry;
|
||||
|
||||
if (element->str_free) {
|
||||
element->str_free(element->str);
|
||||
}
|
||||
|
||||
#ifdef HAVE_LIBTHAI_H
|
||||
overlay_cursor = element->thai_overlays;
|
||||
while (overlay_cursor) {
|
||||
SDL_ToolkitThaiOverlayX11 *overlay;
|
||||
|
||||
overlay = overlay_cursor->entry;
|
||||
SDL_free(overlay->str);
|
||||
SDL_free(overlay);
|
||||
overlay_cursor = overlay_cursor->next;
|
||||
}
|
||||
SDL_ListClear(&element->thai_overlays);
|
||||
#endif
|
||||
|
||||
SDL_free(element);
|
||||
|
||||
cursor = cursor->next;
|
||||
}
|
||||
}
|
||||
|
||||
#define X11Toolkit_FreeTextElements(x) X11Toolkit_FreeTextElementsListContents(x); SDL_ListClear(&x)
|
||||
|
||||
static bool X11Toolkit_ShouldFlipUI(void)
|
||||
{
|
||||
SDL_Locale **current_locales;
|
||||
@@ -744,6 +1158,10 @@ SDL_ToolkitWindowX11 *X11Toolkit_CreateWindowStruct(SDL_Window *parent, SDL_Tool
|
||||
window->fribidi = SDL_FriBidi_Create();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBTHAI_H
|
||||
window->th = SDL_LibThai_Create();
|
||||
#endif
|
||||
|
||||
/* Interface direction */
|
||||
window->flip_interface = X11Toolkit_ShouldFlipUI();
|
||||
|
||||
@@ -1466,7 +1884,7 @@ static void X11Toolkit_CalculateIconControl(SDL_ToolkitControlX11 *base_control)
|
||||
int icon_wh;
|
||||
|
||||
control = (SDL_ToolkitIconControlX11 *)base_control;
|
||||
X11Toolkit_GetTextWidthHeightForFont(control->icon_char_font, &control->icon_char, 1, &icon_char_w, &control->icon_char_h, &control->icon_char_a);
|
||||
X11Toolkit_GetTextWidthHeightForFont(control->icon_char_font, &control->icon_char, 1, &icon_char_w, &control->icon_char_h, &control->icon_char_a, NULL);
|
||||
base_control->rect.w = icon_char_w;
|
||||
base_control->rect.h = control->icon_char_h;
|
||||
icon_wh = SDL_max(icon_char_w, control->icon_char_h) + SDL_TOOLKIT_X11_ELEMENT_PADDING * 2 * base_control->window->iscale;
|
||||
@@ -1632,31 +2050,23 @@ bool X11Toolkit_NotifyControlOfSizeChange(SDL_ToolkitControlX11 *control) {
|
||||
|
||||
static void X11Toolkit_CalculateButtonControl(SDL_ToolkitControlX11 *control) {
|
||||
SDL_ToolkitButtonControlX11 *button_control;
|
||||
int text_d;
|
||||
|
||||
button_control = (SDL_ToolkitButtonControlX11 *)control;
|
||||
X11Toolkit_GetTextWidthHeight(control->window, button_control->data->text, button_control->str_sz, &button_control->text_rect.w, &button_control->text_rect.h, &button_control->text_a, &text_d, NULL);
|
||||
X11Toolkit_GetTextElementsRect(button_control->text, &button_control->text_rect);
|
||||
if (control->do_size) {
|
||||
control->rect.w = SDL_TOOLKIT_X11_ELEMENT_PADDING_3 * 2 * control->window->iscale + button_control->text_rect.w;
|
||||
control->rect.h = SDL_TOOLKIT_X11_ELEMENT_PADDING_3 * 2 * control->window->iscale + button_control->text_rect.h;
|
||||
}
|
||||
button_control->text_rect.x = (control->rect.w - button_control->text_rect.w)/2;
|
||||
button_control->text_rect.y = button_control->text_a + (control->rect.h - button_control->text_rect.h)/2;
|
||||
button_control->text_rect.y = (control->rect.h - button_control->text_rect.h)/2;
|
||||
}
|
||||
|
||||
|
||||
static void X11Toolkit_DrawButtonControl(SDL_ToolkitControlX11 *control) {
|
||||
SDL_ToolkitButtonControlX11 *button_control;
|
||||
char *text;
|
||||
|
||||
button_control = (SDL_ToolkitButtonControlX11 *)control;
|
||||
|
||||
#ifdef HAVE_FRIBIDI_H
|
||||
text = button_control->text;
|
||||
#else
|
||||
text = (char *)button_control->data->text;
|
||||
#endif
|
||||
|
||||
X11_XSetForeground(control->window->display, control->window->ctx, control->window->xcolor[SDL_MESSAGEBOX_COLOR_TEXT].pixel);
|
||||
/* Draw bevel */
|
||||
if (control->state == SDL_TOOLKIT_CONTROL_STATE_X11_PRESSED || control->state == SDL_TOOLKIT_CONTROL_STATE_X11_PRESSED_HELD) {
|
||||
@@ -1738,20 +2148,8 @@ static void X11Toolkit_DrawButtonControl(SDL_ToolkitControlX11 *control) {
|
||||
}
|
||||
}
|
||||
|
||||
X11_XSetForeground(control->window->display, control->window->ctx, control->window->xcolor[SDL_MESSAGEBOX_COLOR_TEXT].pixel);
|
||||
#ifdef X_HAVE_UTF8_STRING
|
||||
if (control->window->utf8) {
|
||||
X11_Xutf8DrawString(control->window->display, control->window->drawable, control->window->font_set, control->window->ctx,
|
||||
control->rect.x + button_control->text_rect.x,
|
||||
control->rect.y + button_control->text_rect.y,
|
||||
text, button_control->str_sz);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
X11_XDrawString(control->window->display, control->window->drawable, control->window->ctx,
|
||||
control->rect.x + button_control->text_rect.x, control->rect.y + button_control->text_rect.y,
|
||||
text, button_control->str_sz);
|
||||
}
|
||||
X11_XSetForeground(control->window->display, control->window->ctx, control->window->xcolor[SDL_MESSAGEBOX_COLOR_TEXT].pixel);
|
||||
X11Toolkit_DrawTextElements(control->window, button_control->text, control->rect.x + button_control->text_rect.x, control->rect.y + button_control->text_rect.y);
|
||||
}
|
||||
|
||||
static void X11Toolkit_OnButtonControlStateChange(SDL_ToolkitControlX11 *control) {
|
||||
@@ -1764,21 +2162,18 @@ static void X11Toolkit_OnButtonControlStateChange(SDL_ToolkitControlX11 *control
|
||||
}
|
||||
|
||||
static void X11Toolkit_DestroyButtonControl(SDL_ToolkitControlX11 *control) {
|
||||
#ifdef HAVE_FRIBIDI_H
|
||||
SDL_ToolkitButtonControlX11 *button_control;
|
||||
|
||||
button_control = (SDL_ToolkitButtonControlX11 *)control;
|
||||
if (button_control->free_text) {
|
||||
SDL_free(button_control->text);
|
||||
}
|
||||
#endif
|
||||
|
||||
X11Toolkit_FreeTextElements(button_control->text);
|
||||
|
||||
SDL_free(control);
|
||||
}
|
||||
|
||||
SDL_ToolkitControlX11 *X11Toolkit_CreateButtonControl(SDL_ToolkitWindowX11 *window, const SDL_MessageBoxButtonData *data) {
|
||||
SDL_ToolkitButtonControlX11 *control;
|
||||
SDL_ToolkitControlX11 *base_control;
|
||||
int text_d;
|
||||
|
||||
control = (SDL_ToolkitButtonControlX11 *)SDL_malloc(sizeof(SDL_ToolkitButtonControlX11));
|
||||
base_control = (SDL_ToolkitControlX11 *)control;
|
||||
@@ -1805,30 +2200,19 @@ SDL_ToolkitControlX11 *X11Toolkit_CreateButtonControl(SDL_ToolkitWindowX11 *wind
|
||||
base_control->is_default_enter = true;
|
||||
base_control->selected = true;
|
||||
}
|
||||
base_control->do_size = false;
|
||||
control->data = data;
|
||||
control->str_sz = SDL_strlen(control->data->text);
|
||||
#ifdef HAVE_FRIBIDI_H
|
||||
if (base_control->window->fribidi) {
|
||||
control->text = SDL_FriBidi_Process(base_control->window->fribidi, (char *)control->data->text, control->str_sz, base_control->window->do_shaping, NULL);
|
||||
if (control->text) {
|
||||
control->free_text = true;
|
||||
control->str_sz = SDL_strlen(control->text);
|
||||
} else {
|
||||
control->text = (char *)control->data->text;
|
||||
control->free_text = false;
|
||||
}
|
||||
} else {
|
||||
control->text = (char *)control->data->text;
|
||||
control->free_text = false;
|
||||
}
|
||||
#endif
|
||||
control->cb = NULL;
|
||||
X11Toolkit_GetTextWidthHeight(base_control->window, control->data->text, control->str_sz, &control->text_rect.w, &control->text_rect.h, &control->text_a, &text_d, NULL);
|
||||
base_control->rect.w = SDL_TOOLKIT_X11_ELEMENT_PADDING_3 * 2 * window->iscale + control->text_rect.w;
|
||||
base_control->rect.h = SDL_TOOLKIT_X11_ELEMENT_PADDING_3 * 2 * window->iscale + control->text_rect.h;
|
||||
control->text_rect.x = control->text_rect.y = 0;
|
||||
control->data = data;
|
||||
#ifdef HAVE_FRIBIDI_H
|
||||
control->text = X11Toolkit_MakeTextElements(base_control->window, (char *)control->data->text, SDL_strlen(control->data->text), NULL);
|
||||
#else
|
||||
control->text = X11Toolkit_MakeTextElements(base_control->window, (char *)control->data->text, SDL_strlen(control->data->text));
|
||||
#endif
|
||||
X11Toolkit_ShapeTextElements(base_control->window, control->text);
|
||||
|
||||
base_control->do_size = true;
|
||||
X11Toolkit_CalculateButtonControl(base_control);
|
||||
base_control->do_size = false;
|
||||
|
||||
X11Toolkit_AddControlToWindow(window, base_control);
|
||||
return base_control;
|
||||
}
|
||||
@@ -1936,6 +2320,10 @@ void X11Toolkit_DestroyWindow(SDL_ToolkitWindowX11 *data) {
|
||||
SDL_FriBidi_Destroy(data->fribidi);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBTHAI_H
|
||||
SDL_LibThai_Destroy(data->th);
|
||||
#endif
|
||||
|
||||
SDL_free(data);
|
||||
}
|
||||
|
||||
@@ -1953,143 +2341,112 @@ static int X11Toolkit_CountLinesOfText(const char *text)
|
||||
static void X11Toolkit_DrawLabelControl(SDL_ToolkitControlX11 *control) {
|
||||
SDL_ToolkitLabelControlX11 *label_control;
|
||||
int i;
|
||||
int x;
|
||||
|
||||
label_control = (SDL_ToolkitLabelControlX11 *)control;
|
||||
X11_XSetForeground(control->window->display, control->window->ctx, control->window->xcolor[SDL_MESSAGEBOX_COLOR_TEXT].pixel);
|
||||
for (i = 0; i < label_control->sz; i++) {
|
||||
x = control->rect.x;
|
||||
#ifdef HAVE_FRIBIDI_H
|
||||
if (control->window->fribidi) {
|
||||
x += label_control->x[i];
|
||||
}
|
||||
#endif
|
||||
#ifdef X_HAVE_UTF8_STRING
|
||||
if (control->window->utf8) {
|
||||
X11_Xutf8DrawString(control->window->display, control->window->drawable, control->window->font_set, control->window->ctx,
|
||||
x, control->rect.y + label_control->y[i],
|
||||
label_control->lines[i], label_control->szs[i]);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
X11_XDrawString(control->window->display, control->window->drawable, control->window->ctx,
|
||||
x, control->rect.y + label_control->y[i],
|
||||
label_control->lines[i], label_control->szs[i]);
|
||||
}
|
||||
X11Toolkit_DrawTextElements(control->window, label_control->lines[i].text, control->rect.x + label_control->lines[i].rect.x, control->rect.y + label_control->lines[i].rect.y);
|
||||
}
|
||||
}
|
||||
|
||||
static void X11Toolkit_DestroyLabelControl(SDL_ToolkitControlX11 *control) {
|
||||
SDL_ToolkitLabelControlX11 *label_control;
|
||||
int i;
|
||||
|
||||
label_control = (SDL_ToolkitLabelControlX11 *)control;
|
||||
#ifdef HAVE_FRIBIDI_H
|
||||
if (control->window->fribidi) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < label_control->sz; i++) {
|
||||
if (label_control->free_lines[i]) {
|
||||
SDL_free(label_control->lines[i]);
|
||||
}
|
||||
}
|
||||
SDL_free(label_control->x);
|
||||
SDL_free(label_control->free_lines);
|
||||
SDL_free(label_control->w);
|
||||
SDL_free(label_control->par_types);
|
||||
for (i = 0; i < label_control->sz; i++) {
|
||||
X11Toolkit_FreeTextElements(label_control->lines[i].text);
|
||||
}
|
||||
#endif
|
||||
SDL_free(label_control->lines);
|
||||
SDL_free(label_control->szs);
|
||||
SDL_free(label_control->y);
|
||||
SDL_free(label_control);
|
||||
}
|
||||
|
||||
static void X11Toolkit_CalculateLabelControl(SDL_ToolkitControlX11 *base_control) {
|
||||
SDL_ToolkitLabelControlX11 *control;
|
||||
int last_h;
|
||||
int ascent;
|
||||
int descent;
|
||||
int font_h;
|
||||
int w;
|
||||
int h;
|
||||
int i;
|
||||
#ifdef HAVE_FRIBIDI_H
|
||||
FriBidiParType first_ndn_dir;
|
||||
int last_ndn;
|
||||
#endif
|
||||
|
||||
last_h = 0;
|
||||
control = (SDL_ToolkitLabelControlX11 *)base_control;
|
||||
for (i = 0; i < control->sz; i++) {
|
||||
X11Toolkit_GetTextWidthHeight(base_control->window, control->lines[i], control->szs[i], &w, &h, &ascent, &descent, &font_h);
|
||||
base_control->rect.w = SDL_max(base_control->rect.w, w);
|
||||
|
||||
if (i > 0) {
|
||||
control->y[i] = font_h + control->y[i-1];
|
||||
} else {
|
||||
control->y[i] = ascent;
|
||||
}
|
||||
|
||||
last_h = h;
|
||||
|
||||
if (base_control->do_size) {
|
||||
base_control->rect.w = 0;
|
||||
base_control->rect.h = 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < control->sz; i++) {
|
||||
int font_h;
|
||||
|
||||
font_h = X11Toolkit_GetTextElementsRect(control->lines[i].text, &control->lines[i].rect);
|
||||
|
||||
if (base_control->do_size) {
|
||||
base_control->rect.w = SDL_max(base_control->rect.w, control->lines[i].rect.w);
|
||||
}
|
||||
|
||||
if (i > 0) {
|
||||
control->lines[i].rect.y = font_h + control->lines[i - 1].rect.y;
|
||||
} else {
|
||||
control->lines[i].rect.y = 0;
|
||||
}
|
||||
}
|
||||
base_control->rect.h = control->y[control->sz -1] + last_h;
|
||||
|
||||
#ifdef HAVE_FRIBIDI_H
|
||||
if (base_control->window->fribidi) {
|
||||
FriBidiParType first_ndn_dir;
|
||||
int last_ndn;
|
||||
|
||||
first_ndn_dir = FRIBIDI_PAR_LTR;
|
||||
for (i = 0; i < control->sz; i++) {
|
||||
if (control->par_types[i] != FRIBIDI_PAR_ON) {
|
||||
first_ndn_dir = control->par_types[i];
|
||||
if (control->lines[i].par != FRIBIDI_PAR_ON) {
|
||||
first_ndn_dir = control->lines[i].par;
|
||||
}
|
||||
}
|
||||
|
||||
last_ndn = -1;
|
||||
for (i = 0; i < control->sz; i++) {
|
||||
switch (control->par_types[i]) {
|
||||
switch (control->lines[i].par) {
|
||||
case FRIBIDI_PAR_LTR:
|
||||
control->x[i] = 0;
|
||||
control->lines[i].rect.x = 0;
|
||||
last_ndn = i;
|
||||
break;
|
||||
case FRIBIDI_PAR_RTL:
|
||||
control->x[i] = base_control->rect.w - control->w[i];
|
||||
control->lines[i].rect.x = base_control->rect.w - control->lines[i].rect.w;
|
||||
last_ndn = i;
|
||||
break;
|
||||
default:
|
||||
if (last_ndn != -1) {
|
||||
if (control->par_types[last_ndn] == FRIBIDI_PAR_RTL) {
|
||||
control->x[i] = base_control->rect.w - control->w[i];
|
||||
if (control->lines[last_ndn].par == FRIBIDI_PAR_RTL) {
|
||||
control->lines[i].rect.x = base_control->rect.w - control->lines[i].rect.w;
|
||||
} else {
|
||||
control->x[i] = 0;
|
||||
control->lines[i].rect.x = 0;
|
||||
}
|
||||
} else {
|
||||
if (first_ndn_dir == FRIBIDI_PAR_RTL) {
|
||||
control->x[i] = base_control->rect.w - control->w[i];
|
||||
control->lines[i].rect.x = base_control->rect.w - control->lines[i].rect.w;
|
||||
} else {
|
||||
control->x[i] = 0;
|
||||
control->lines[i].rect.x = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (base_control->do_size && control->sz) {
|
||||
base_control->rect.h = control->lines[control->sz - 1].rect.y + control->lines[control->sz - 1].rect.h;
|
||||
}
|
||||
}
|
||||
|
||||
SDL_ToolkitControlX11 *X11Toolkit_CreateLabelControl(SDL_ToolkitWindowX11 *window, char *utf8) {
|
||||
SDL_ToolkitLabelControlX11 *control;
|
||||
SDL_ToolkitControlX11 *base_control;
|
||||
#ifdef HAVE_FRIBIDI_H
|
||||
FriBidiParType first_ndn_dir;
|
||||
int last_ndn;
|
||||
#endif
|
||||
int font_h;
|
||||
int last_h;
|
||||
int ascent;
|
||||
int descent;
|
||||
int i;
|
||||
|
||||
|
||||
if (!utf8) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!SDL_strcmp(utf8, "")) {
|
||||
return NULL;
|
||||
}
|
||||
control = (SDL_ToolkitLabelControlX11 *)SDL_malloc(sizeof(SDL_ToolkitLabelControlX11));
|
||||
base_control = (SDL_ToolkitControlX11 *)control;
|
||||
if (!control) {
|
||||
@@ -2109,113 +2466,46 @@ SDL_ToolkitControlX11 *X11Toolkit_CreateLabelControl(SDL_ToolkitWindowX11 *windo
|
||||
base_control->rect.h = 0;
|
||||
base_control->is_default_enter = false;
|
||||
base_control->is_default_esc = false;
|
||||
|
||||
control->sz = X11Toolkit_CountLinesOfText(utf8);
|
||||
control->lines = (char **)SDL_malloc(sizeof(char *) * control->sz);
|
||||
control->y = (int *)SDL_calloc(control->sz, sizeof(int));
|
||||
control->szs = (size_t *)SDL_calloc(control->sz, sizeof(size_t));
|
||||
#ifdef HAVE_FRIBIDI_H
|
||||
if (base_control->window->fribidi) {
|
||||
control->x = (int *)SDL_calloc(control->sz, sizeof(int));
|
||||
control->free_lines = (bool *)SDL_calloc(control->sz, sizeof(bool));
|
||||
control->par_types = (FriBidiParType *)SDL_calloc(control->sz, sizeof(FriBidiParType));
|
||||
control->w = (int *)SDL_calloc(control->sz, sizeof(int));
|
||||
}
|
||||
#endif
|
||||
last_h = 0;
|
||||
control->lines = SDL_calloc(control->sz, sizeof(SDL_ToolkitLabelControlLineX11));
|
||||
for (i = 0; i < control->sz; i++) {
|
||||
const char *lf = SDL_strchr(utf8, '\n');
|
||||
const int length = lf ? (lf - utf8) : SDL_strlen(utf8);
|
||||
int w;
|
||||
int h;
|
||||
|
||||
#ifdef HAVE_FRIBIDI_H
|
||||
if (base_control->window->fribidi) {
|
||||
control->lines[i] = SDL_FriBidi_Process(base_control->window->fribidi, utf8, length, base_control->window->do_shaping, &control->par_types[i]);
|
||||
control->szs[i] = SDL_strlen(control->lines[i]);
|
||||
control->free_lines[i] = true;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
control->lines[i] = utf8;
|
||||
control->szs[i] = length;
|
||||
#ifdef HAVE_FRIBIDI_H
|
||||
control->free_lines[i] = false;
|
||||
#endif
|
||||
}
|
||||
X11Toolkit_GetTextWidthHeight(window, control->lines[i], control->szs[i], &w, &h, &ascent, &descent, &font_h);
|
||||
#ifdef HAVE_FRIBIDI_H
|
||||
if (base_control->window->fribidi) {
|
||||
control->w[i] = w;
|
||||
}
|
||||
#endif
|
||||
base_control->rect.w = SDL_max(base_control->rect.w, w);
|
||||
|
||||
if (lf && (lf > control->lines[i]) && (lf[-1] == '\r')) {
|
||||
control->szs[i]--;
|
||||
int sz;
|
||||
|
||||
sz = length;
|
||||
if (lf && (lf > utf8) && (lf[-1] == '\r')) {
|
||||
sz--;
|
||||
}
|
||||
|
||||
if (i > 0) {
|
||||
control->y[i] = font_h + control->y[i-1];
|
||||
} else {
|
||||
control->y[i] = ascent;
|
||||
}
|
||||
last_h = h;
|
||||
#ifdef HAVE_FRIBIDI_H
|
||||
control->lines[i].text = X11Toolkit_MakeTextElements(base_control->window, (char *)utf8, sz, &control->lines[i].par);
|
||||
#else
|
||||
control->lines[i].text = X11Toolkit_MakeTextElements(base_control->window, (char *)utf8, sz);
|
||||
#endif
|
||||
X11Toolkit_ShapeTextElements(base_control->window, control->lines[i].text);
|
||||
|
||||
utf8 += length + 1;
|
||||
|
||||
if (!lf) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
base_control->rect.h = control->y[control->sz -1] + last_h;
|
||||
#ifdef HAVE_FRIBIDI_H
|
||||
if (base_control->window->fribidi) {
|
||||
first_ndn_dir = FRIBIDI_PAR_LTR;
|
||||
for (i = 0; i < control->sz; i++) {
|
||||
if (control->par_types[i] != FRIBIDI_PAR_ON) {
|
||||
first_ndn_dir = control->par_types[i];
|
||||
}
|
||||
}
|
||||
|
||||
last_ndn = -1;
|
||||
for (i = 0; i < control->sz; i++) {
|
||||
switch (control->par_types[i]) {
|
||||
case FRIBIDI_PAR_LTR:
|
||||
control->x[i] = 0;
|
||||
last_ndn = i;
|
||||
break;
|
||||
case FRIBIDI_PAR_RTL:
|
||||
control->x[i] = base_control->rect.w - control->w[i];
|
||||
last_ndn = i;
|
||||
break;
|
||||
default:
|
||||
if (last_ndn != -1) {
|
||||
if (control->par_types[last_ndn] == FRIBIDI_PAR_RTL) {
|
||||
control->x[i] = base_control->rect.w - control->w[i];
|
||||
} else {
|
||||
control->x[i] = 0;
|
||||
}
|
||||
} else {
|
||||
if (first_ndn_dir == FRIBIDI_PAR_RTL) {
|
||||
control->x[i] = base_control->rect.w - control->w[i];
|
||||
} else {
|
||||
control->x[i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
base_control->do_size = true;
|
||||
X11Toolkit_CalculateLabelControl(base_control);
|
||||
base_control->do_size = false;
|
||||
X11Toolkit_AddControlToWindow(window, base_control);
|
||||
|
||||
return base_control;
|
||||
}
|
||||
|
||||
int X11Toolkit_GetIconControlCharY(SDL_ToolkitControlX11 *control) {
|
||||
SDL_ToolkitIconControlX11 *icon_control;
|
||||
int X11Toolkit_GetLabelControlFirstLineHeight(SDL_ToolkitControlX11 *control) {
|
||||
SDL_ToolkitLabelControlX11 *label_control;
|
||||
|
||||
icon_control = (SDL_ToolkitIconControlX11 *)control;
|
||||
return icon_control->icon_char_y - icon_control->icon_char_a + icon_control->icon_char_h/4;
|
||||
label_control = (SDL_ToolkitLabelControlX11 *)control;
|
||||
|
||||
return label_control->lines[0].rect.h;
|
||||
}
|
||||
|
||||
void X11Toolkit_SignalWindowClose(SDL_ToolkitWindowX11 *data) {
|
||||
|
||||
@@ -32,6 +32,9 @@
|
||||
#ifdef HAVE_FRIBIDI_H
|
||||
#include "../../core/unix/SDL_fribidi.h"
|
||||
#endif
|
||||
#ifdef HAVE_LIBTHAI_H
|
||||
#include "../../core/unix/SDL_libthai.h"
|
||||
#endif
|
||||
|
||||
#ifdef SDL_VIDEO_DRIVER_X11
|
||||
|
||||
@@ -50,6 +53,22 @@ typedef enum SDL_ToolkitChildModeX11
|
||||
SDL_TOOLKIT_WINDOW_MODE_X11_TOOLTIP
|
||||
} SDL_ToolkitWindowModeX11;
|
||||
|
||||
typedef enum SDL_ToolkitThaiEncodingX11
|
||||
{
|
||||
SDL_TOOLKIT_THAI_ENCODING_X11_NONE,
|
||||
SDL_TOOLKIT_THAI_ENCODING_X11_TIS, /* -0 */
|
||||
SDL_TOOLKIT_THAI_ENCODING_X11_TIS_WIN, /* -2 */
|
||||
SDL_TOOLKIT_THAI_ENCODING_X11_TIS_MAC, /* -1 */
|
||||
SDL_TOOLKIT_THAI_ENCODING_X11_8859,
|
||||
SDL_TOOLKIT_THAI_ENCODING_X11_UNICODE
|
||||
} SDL_ToolkitThaiEncodingX11;
|
||||
|
||||
typedef enum SDL_ToolkitThaiFontX11
|
||||
{
|
||||
SDL_TOOLKIT_THAI_FONT_X11_OFFSET,
|
||||
SDL_TOOLKIT_THAI_FONT_X11_CELL
|
||||
} SDL_ToolkitThaiFontX11;
|
||||
|
||||
typedef struct SDL_ToolkitWindowX11
|
||||
{
|
||||
/* Locale */
|
||||
@@ -119,7 +138,9 @@ typedef struct SDL_ToolkitWindowX11
|
||||
/* Font */
|
||||
XFontSet font_set; // for UTF-8 systems
|
||||
XFontStruct *font_struct; // Latin1 (ASCII) fallback.
|
||||
|
||||
SDL_ToolkitThaiEncodingX11 thai_encoding;
|
||||
SDL_ToolkitThaiFontX11 thai_font;
|
||||
|
||||
/* Control colors */
|
||||
const SDL_MessageBoxColor *color_hints;
|
||||
XColor xcolor[SDL_MESSAGEBOX_COLOR_COUNT];
|
||||
@@ -164,6 +185,10 @@ typedef struct SDL_ToolkitWindowX11
|
||||
bool do_shaping;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LIBTHAI_H
|
||||
SDL_LibThai *th;
|
||||
#endif
|
||||
|
||||
bool flip_interface;
|
||||
} SDL_ToolkitWindowX11;
|
||||
|
||||
@@ -231,10 +256,10 @@ extern bool X11Toolkit_NotifyControlOfSizeChange(SDL_ToolkitControlX11 *control)
|
||||
|
||||
/* ICON CONTROL FUNCTIONS */
|
||||
extern SDL_ToolkitControlX11 *X11Toolkit_CreateIconControl(SDL_ToolkitWindowX11 *window, SDL_MessageBoxFlags flags);
|
||||
extern int X11Toolkit_GetIconControlCharY(SDL_ToolkitControlX11 *control);
|
||||
|
||||
/* LABEL CONTROL FUNCTIONS */
|
||||
extern SDL_ToolkitControlX11 *X11Toolkit_CreateLabelControl(SDL_ToolkitWindowX11 *window, char *utf8);
|
||||
extern int X11Toolkit_GetLabelControlFirstLineHeight(SDL_ToolkitControlX11 *control);
|
||||
|
||||
/* BUTTON CONTROL FUNCTIONS */
|
||||
extern SDL_ToolkitControlX11 *X11Toolkit_CreateButtonControl(SDL_ToolkitWindowX11 *window, const SDL_MessageBoxButtonData *data);
|
||||
|
||||
@@ -164,6 +164,11 @@ int main(int argc, char *argv[])
|
||||
quit(1);
|
||||
}
|
||||
|
||||
success = SDL_ShowSimpleMessageBox(0,
|
||||
"No icon",
|
||||
"This is a MessageBox with no icon!",
|
||||
NULL);
|
||||
|
||||
/* Google says this is Traditional Chinese for "beef with broccoli" */
|
||||
success = SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR,
|
||||
"UTF-8 Simple MessageBox",
|
||||
|
||||
Reference in New Issue
Block a user