mirror of
https://github.com/fltk/fltk.git
synced 2026-05-25 00:53:39 +08:00
Emoji input: remove context-dependent unicode points from output of emoji palette.
The character palette allowing to input emojis in text generates in some cases a series of unicode points to represent a single emoji. These series contain various kinds of unicode points with context-dependent meaning. This commit prevents such context- dependent unicodepoints from being inserted in FLTK text because FLTK text edition mechanism is not ready to handle properly context dependency in edited UTF-8 text.
This commit is contained in:
+16
-1
@@ -2954,8 +2954,23 @@ static FLTextInputContext* fltextinputcontext_instance = nil;
|
||||
BOOL has_text_key = Fl::e_keysym <= '~' || Fl::e_keysym == FL_Iso_Key ||
|
||||
(Fl::e_keysym >= FL_KP && Fl::e_keysym <= FL_KP_Last && Fl::e_keysym != FL_KP_Enter);
|
||||
// insertText sent during handleEvent of a key without text cannot be processed in a single FL_KEYBOARD event.
|
||||
// Occurs with deadkey followed by non-text key
|
||||
// Occurs with deadkey followed by non-text key. Occurs also with emoji palette.
|
||||
if (!in_key_event || !has_text_key) {
|
||||
if (fl_utf_nb_char((const uchar*)Fl::e_text, Fl::e_length) > 1) {
|
||||
// Some emojis are expressed by a series of Unicode points
|
||||
const char *p = Fl::e_text, *end = Fl::e_text + Fl::e_length;
|
||||
int len;
|
||||
while (p < end) { // loop over all unicode points of the series
|
||||
unsigned u = fl_utf8decode(p, end, &len); // extract one such unicode point
|
||||
if ((u >= 0xFE00 && u <= 0xFE0F) // variation selectors
|
||||
|| u == 0x200D // zero-width joiner
|
||||
|| (u >= 0x1F3FB && u <= 0x1F3FF) // EMOJI MODIFIERS FITZPATRICK TYPE
|
||||
) { // remove context-dependent unicode points
|
||||
memmove((void*)p, p + len, (end - (p+len)) + 1);
|
||||
Fl::e_length -= len; end -= len;
|
||||
} else p += len; // keep other unicode points
|
||||
}
|
||||
}
|
||||
Fl::handle(FL_KEYBOARD, target);
|
||||
Fl::e_length = 0;
|
||||
}
|
||||
|
||||
+12
-4
@@ -1562,8 +1562,8 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
|
||||
if (uMsg == WM_CHAR || uMsg == WM_SYSCHAR) {
|
||||
wchar_t u = (wchar_t)wParam;
|
||||
// Windows emoji palette triggered with Windows + dot sends 2 or more WM_CHAR messages:
|
||||
// the 2 components of a surrogate pair, or variation selectors, or zero-width stuff,
|
||||
// or extra Unicode points.
|
||||
// the 2 components of a surrogate pair, or variation selectors, or zero-width joiner,
|
||||
// or emoji modifiers FITZPATRICK or extra Unicode points.
|
||||
if (u >= 0xD800 && u <= 0xDFFF) { // handle the 2 components of a surrogate pair
|
||||
static wchar_t surrogate_pair[2];
|
||||
if (IS_HIGH_SURROGATE(u)) {
|
||||
@@ -1572,10 +1572,18 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
|
||||
return 0; // and wait for next WM_CHAR message that will give the 2nd member
|
||||
} else {
|
||||
surrogate_pair[1] = u; // memorize the 2nd member of the pair
|
||||
unsigned u32 = // convert surrogate pair to UTF-32
|
||||
0x10000 + ((surrogate_pair[0] & 0x3ff) << 10) + (surrogate_pair[1] & 0x3ff);
|
||||
if (u32 >= 0x1F3FB && u32 <= 0x1F3FF) { // emoji modifiers FITZPATRICK
|
||||
Fl::e_length = 0; // skip them
|
||||
return 0;
|
||||
}
|
||||
Fl::e_length = fl_utf8fromwc(buffer, 1024, surrogate_pair, 2); // transform to UTF-8
|
||||
}
|
||||
} else if ((u >= 0xFE00 && u <= 0xFE0F) || (u >= 0x200B && u <= 0x200D)) {
|
||||
Fl::e_length = 0; // skip variation selectors and zero-width Unicode points
|
||||
} else if ( (u >= 0xFE00 && u <= 0xFE0F) // variation selectors
|
||||
|| u == 0x200D // zero-width joiner
|
||||
) {
|
||||
Fl::e_length = 0; // skip these context-dependent Unicode points
|
||||
return 0;
|
||||
} else {
|
||||
Fl::e_length = fl_utf8fromwc(buffer, 1024, &u, 1); // process regular Unicode point
|
||||
|
||||
Reference in New Issue
Block a user