Merge pull request #1472 from nixbody/cffi-unicode-fixes

UNICODE fixes (clipboard, window title, file dialogs, paths, font glyphs, ...)
This commit is contained in:
tobil4sk
2024-07-07 23:10:43 +01:00
committed by GitHub
3 changed files with 116 additions and 107 deletions

View File

@@ -52,6 +52,7 @@
#include <locale>
#include <codecvt>
#endif
#include <memory>
#include <cstdlib>
#include <cstring>
@@ -134,15 +135,82 @@ namespace lime {
}
std::string wstring_utf8 (const std::wstring& val) {
std::string out;
unsigned int codepoint = 0;
for (const wchar_t chr : val) {
if (chr >= 0xd800 && chr <= 0xdbff) {
codepoint = ((chr - 0xd800) << 10) + 0x10000;
} else {
if (chr >= 0xdc00 && chr <= 0xdfff) {
codepoint |= chr - 0xdc00;
} else {
codepoint = chr;
}
if (codepoint <= 0x7f) {
out.append (1, static_cast<char> (codepoint));
} else if (codepoint <= 0x7ff) {
out.append (1, static_cast<char> (0xc0 | ((codepoint >> 6) & 0x1f)));
out.append (1, static_cast<char> (0x80 | (codepoint & 0x3f)));
} else if (codepoint <= 0xffff) {
out.append (1, static_cast<char> (0xe0 | ((codepoint >> 12) & 0x0f)));
out.append (1, static_cast<char> (0x80 | ((codepoint >> 6) & 0x3f)));
out.append (1, static_cast<char> (0x80 | (codepoint & 0x3f)));
} else {
out.append (1, static_cast<char> (0xf0 | ((codepoint >> 18) & 0x07)));
out.append (1, static_cast<char> (0x80 | ((codepoint >> 12) & 0x3f)));
out.append (1, static_cast<char> (0x80 | ((codepoint >> 6) & 0x3f)));
out.append (1, static_cast<char> (0x80 | (codepoint & 0x3f)));
}
codepoint = 0;
}
}
return out;
}
vbyte* hl_wstring_to_utf8_bytes (const std::wstring& val) {
const std::string utf8 (wstring_utf8 (val));
vbyte* const bytes = hl_alloc_bytes (utf8.size () + 1);
std::memcpy(bytes, utf8.c_str (), utf8.size () + 1);
return bytes;
}
std::wstring* hxstring_to_wstring (HxString val) {
if (val.c_str ()) {
std::string _val = std::string (val.c_str ());
#ifdef HX_WINDOWS
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
return new std::wstring (converter.from_bytes (_val));
return new std::wstring (hxs_wchar (val, nullptr));
#else
const std::string _val (hxs_utf8 (val, nullptr));
return new std::wstring (_val.begin (), _val.end ());
#endif
@@ -196,34 +264,6 @@ namespace lime {
}
vbyte* wstring_to_vbytes (std::wstring* val) {
if (val) {
#ifdef HX_WINDOWS
int size = std::wcslen (val->c_str ());
char* result = (char*)malloc (size + 1);
std::wcstombs (result, val->c_str (), size);
result[size] = '\0';
return (vbyte*)result;
#else
std::string _val = std::string (val->begin (), val->end ());
int size = std::strlen (_val.c_str ());
char* result = (char*)malloc (size + 1);
std::strncpy (result, _val.c_str (), size);
result[size] = '\0';
return (vbyte*)result;
#endif
} else {
return 0;
}
}
value lime_application_create () {
Application* application = CreateApplication ();
@@ -522,7 +562,7 @@ namespace lime {
value lime_bytes_read_file (HxString path, value bytes) {
Bytes data (bytes);
data.ReadFile (path.c_str ());
data.ReadFile (hxs_utf8 (path, nullptr));
return data.Value (bytes);
}
@@ -622,7 +662,7 @@ namespace lime {
void lime_clipboard_set_text (HxString text) {
Clipboard::SetText (text.c_str ());
Clipboard::SetText (hxs_utf8 (text, nullptr));
}
@@ -769,9 +809,9 @@ namespace lime {
if (path) {
vbyte* _path = wstring_to_vbytes (path);
vbyte* const result = hl_wstring_to_utf8_bytes (*path);
delete path;
return _path;
return result;
} else {
@@ -835,9 +875,9 @@ namespace lime {
if (path) {
vbyte* _path = wstring_to_vbytes (path);
vbyte* const result = hl_wstring_to_utf8_bytes (*path);
delete path;
return _path;
return result;
} else {
@@ -906,8 +946,7 @@ namespace lime {
for (int i = 0; i < files.size (); i++) {
vbyte* _file = wstring_to_vbytes (files[i]);
*resultData++ = _file;
*resultData++ = hl_wstring_to_utf8_bytes (*files[i]);
delete files[i];
}
@@ -970,9 +1009,9 @@ namespace lime {
if (path) {
vbyte* _path = wstring_to_vbytes (path);
vbyte* const result = hl_wstring_to_utf8_bytes (*path);
delete path;
return _path;
return result;
} else {
@@ -1143,12 +1182,11 @@ namespace lime {
#ifdef LIME_FREETYPE
Font *font = (Font*)fontHandle->ptr;
wchar_t *name = font->GetFamilyName ();
int size = std::wcslen (name);
char* result = (char*)malloc (size + 1);
std::wcstombs (result, name, size);
result[size] = '\0';
if (!name)
return nullptr;
vbyte* const result = hl_wstring_to_utf8_bytes (name);
delete name;
return (vbyte*)result;
return result;
#else
return 0;
#endif
@@ -1160,7 +1198,7 @@ namespace lime {
#ifdef LIME_FREETYPE
Font *font = (Font*)val_data (fontHandle);
return font->GetGlyphIndex ((char*)character.c_str ());
return font->GetGlyphIndex (hxs_utf8 (character, nullptr));
#else
return -1;
#endif
@@ -1184,7 +1222,7 @@ namespace lime {
#ifdef LIME_FREETYPE
Font *font = (Font*)val_data (fontHandle);
return (value)font->GetGlyphIndices (true, (char*)characters.c_str ());
return (value)font->GetGlyphIndices (true, hxs_utf8 (characters, nullptr));
#else
return alloc_null ();
#endif
@@ -2361,7 +2399,7 @@ namespace lime {
value lime_jpeg_decode_file (HxString path, bool decodeData, value buffer) {
ImageBuffer imageBuffer (buffer);
Resource resource = Resource (path.c_str ());
Resource resource = Resource (hxs_utf8 (path, nullptr));
#ifdef LIME_JPEG
if (JPEG::Decode (&resource, &imageBuffer, decodeData)) {
@@ -2599,7 +2637,7 @@ namespace lime {
value lime_png_decode_file (HxString path, bool decodeData, value buffer) {
ImageBuffer imageBuffer (buffer);
Resource resource = Resource (path.c_str ());
Resource resource = Resource (hxs_utf8 (path, nullptr));
#ifdef LIME_PNG
if (PNG::Decode (&resource, &imageBuffer, decodeData)) {
@@ -2704,13 +2742,9 @@ namespace lime {
if (model) {
int size = std::wcslen (model->c_str ());
char* result = (char*)malloc (size + 1);
std::wcstombs (result, model->c_str (), size);
result[size] = '\0';
vbyte* const result = hl_wstring_to_utf8_bytes (*model);
delete model;
return (vbyte*)result;
return result;
}
@@ -2748,13 +2782,9 @@ namespace lime {
if (vendor) {
int size = std::wcslen (vendor->c_str ());
char* result = (char*)malloc (size + 1);
std::wcstombs (result, vendor->c_str (), size);
result[size] = '\0';
vbyte* const result = hl_wstring_to_utf8_bytes (*vendor);
delete vendor;
return (vbyte*)result;
return result;
}
@@ -2767,7 +2797,7 @@ namespace lime {
value lime_system_get_directory (int type, HxString company, HxString title) {
std::wstring* path = System::GetDirectory ((SystemDirectory)type, company.c_str (), title.c_str ());
std::wstring* path = System::GetDirectory ((SystemDirectory)type, hxs_utf8 (company, nullptr), hxs_utf8 (title, nullptr));
if (path) {
@@ -2792,13 +2822,9 @@ namespace lime {
if (path) {
int size = std::wcslen (path->c_str ());
char* result = (char*)malloc (size + 1);
std::wcstombs (result, path->c_str (), size);
result[size] = '\0';
vbyte* const result = hl_wstring_to_utf8_bytes (*path);
delete path;
return (vbyte*)result;
return result;
}
@@ -2886,13 +2912,9 @@ namespace lime {
if (label) {
int size = std::wcslen (label->c_str ());
char* result = (char*)malloc (size + 1);
std::wcstombs (result, label->c_str (), size);
result[size] = '\0';
vbyte* const result = hl_wstring_to_utf8_bytes (*label);
delete label;
return (vbyte*)result;
return result;
}
@@ -2930,13 +2952,9 @@ namespace lime {
if (name) {
int size = std::wcslen (name->c_str ());
char* result = (char*)malloc (size + 1);
std::wcstombs (result, name->c_str (), size);
result[size] = '\0';
vbyte* const result = hl_wstring_to_utf8_bytes (*name);
delete name;
return (vbyte*)result;
return result;
}
@@ -2974,14 +2992,9 @@ namespace lime {
if (version) {
int size = std::wcslen (version->c_str ());
char* result = (char*)malloc (size + 1);
std::wcstombs (result, version->c_str (), size);
result[size] = '\0';
vbyte* const result = hl_wstring_to_utf8_bytes (*version);
delete version;
return (vbyte*)result;
return result;
}
#endif
@@ -3134,7 +3147,7 @@ namespace lime {
void lime_window_alert (value window, HxString message, HxString title) {
Window* targetWindow = (Window*)val_data (window);
targetWindow->Alert (message.c_str (), title.c_str ());
targetWindow->Alert (hxs_utf8 (message, nullptr), hxs_utf8 (title, nullptr));
}
@@ -3142,8 +3155,8 @@ namespace lime {
HL_PRIM void HL_NAME(hl_window_alert) (HL_CFFIPointer* window, hl_vstring* message, hl_vstring* title) {
Window* targetWindow = (Window*)window->ptr;
const char *cmessage = message ? hl_to_utf8(message->bytes) : NULL;
const char *ctitle = title ? hl_to_utf8(title->bytes) : NULL;
const char *cmessage = message ? hl_to_utf8(message->bytes) : nullptr;
const char *ctitle = title ? hl_to_utf8(title->bytes) : nullptr;
targetWindow->Alert (cmessage, ctitle);
}
@@ -3223,7 +3236,7 @@ namespace lime {
value lime_window_create (value application, int width, int height, int flags, HxString title) {
Window* window = CreateWindow ((Application*)val_data (application), width, height, flags, title.c_str ());
Window* window = CreateWindow ((Application*)val_data (application), width, height, flags, hxs_utf8 (title, nullptr));
return CFFIPointer (window, gc_window);
}
@@ -3788,13 +3801,14 @@ namespace lime {
value lime_window_set_title (value window, HxString title) {
Window* targetWindow = (Window*)val_data (window);
const char* result = targetWindow->SetTitle (title.c_str ());
const char* titleUtf8 = hxs_utf8 (title, nullptr);
const char* result = targetWindow->SetTitle (titleUtf8);
if (result) {
value _result = alloc_string (result);
if (result != title.c_str ()) {
if (result != titleUtf8) {
free ((char*) result);

View File

@@ -188,10 +188,11 @@ class Font
public function getGlyphs(characters:String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^`'\"/\\&*()[]{}<>|:;_-+=?,. "):Array<Glyph>
{
#if (lime_cffi && !macro)
var glyphs:Dynamic = NativeCFFI.lime_font_get_glyph_indices(src, characters);
// lime_font_get_glyph_indices returns Array<Int>
// cast it to Array<Glyph> instead (Glyph is an abstract)
return cast glyphs;
#if hl
return [for (index in NativeCFFI.lime_font_get_glyph_indices(src, characters)) new Glyph(index)];
#else
return NativeCFFI.lime_font_get_glyph_indices(src, characters);
#end
#else
return null;
#end

View File

@@ -113,10 +113,7 @@ class FileDialog
#if (!macro && lime_cffi)
#if hl
var bytes = NativeCFFI.lime_file_dialog_open_file(title, filter, defaultPath);
if (bytes != null)
{
path = @:privateAccess String.fromUTF8(cast bytes);
}
path = bytes != null ? @:privateAccess String.fromUTF8(cast bytes) : null;
#else
path = NativeCFFI.lime_file_dialog_open_file(title, filter, defaultPath);
#end
@@ -157,10 +154,7 @@ class FileDialog
#if (!macro && lime_cffi)
#if hl
var bytes = NativeCFFI.lime_file_dialog_open_directory(title, filter, defaultPath);
if (bytes != null)
{
path = @:privateAccess String.fromUTF8(cast bytes);
}
path = bytes != null ? @:privateAccess String.fromUTF8(cast bytes) : null;
#else
path = NativeCFFI.lime_file_dialog_open_directory(title, filter, defaultPath);
#end
@@ -331,7 +325,7 @@ class FileDialog
#if (!macro && lime_cffi)
#if hl
var bytes = NativeCFFI.lime_file_dialog_save_file(title, filter, defaultPath);
path = @:privateAccess String.fromUTF8(cast bytes);
path = bytes != null ? @:privateAccess String.fromUTF8(cast bytes) : null;
#else
path = NativeCFFI.lime_file_dialog_save_file(title, filter, defaultPath);
#end