This fixes the behavior in notepad, with Japanese ibus-mozc IME, when typing "NIHONGO-SPACE-NO", or with Korean ibus-hangul when typing "GA-NA-DA". The latter still has an issue with the last character not appearing in the a composition but I believe it is unrelated to comctl32 and will be fixed by some future imm32 changes.
-- v3: user32: Keep and display composition separate from the selection. comctl32/edit: Keep and display composition separate from the selection.
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53860 --- dlls/comctl32/edit.c | 196 ++++++++++++++++++++++++------------------- 1 file changed, 111 insertions(+), 85 deletions(-)
diff --git a/dlls/comctl32/edit.c b/dlls/comctl32/edit.c index 883dd5d9145..0d7c2b14dcc 100644 --- a/dlls/comctl32/edit.c +++ b/dlls/comctl32/edit.c @@ -140,8 +140,8 @@ typedef struct /* * IME Data */ - UINT composition_len; /* length of composition, 0 == no composition */ - int composition_start; /* the character position for the composition */ + LPWSTR composition_text; /* the contents of the composition string */ + SCRIPT_STRING_ANALYSIS composition_ssa; UINT ime_status; /* IME status flag */ /* * Uniscribe Data @@ -318,6 +318,30 @@ static inline void EDIT_InvalidateUniscribeData(EDITSTATE *es) } }
+static SCRIPT_STRING_ANALYSIS EDIT_UpdateUniscribeData_composition(EDITSTATE *es, HDC dc, INT length) +{ + if (!es->composition_ssa) + { + HFONT old_font = NULL; + HDC udc = dc; + + if (!udc) + udc = GetDC(es->hwndSelf); + if (es->font) + old_font = SelectObject(udc, es->font); + + ScriptStringAnalyse(udc, es->composition_text, length, (1.5*length+16), -1, SSA_LINK|SSA_FALLBACK|SSA_GLYPHS, + -1, NULL, NULL, NULL, NULL, NULL, &es->composition_ssa); + + if (es->font) + SelectObject(udc, old_font); + if (udc != dc) + ReleaseDC(es->hwndSelf, udc); + } + + return es->composition_ssa; +} + static SCRIPT_STRING_ANALYSIS EDIT_UpdateUniscribeData_linedef(EDITSTATE *es, HDC dc, LINEDEF *line_def) { if (!line_def) @@ -2043,6 +2067,50 @@ static void EDIT_MoveWordForward(EDITSTATE *es, BOOL extend) }
+static INT EDIT_PaintComposition(EDITSTATE *es, HDC dc, INT x, INT y) +{ + LOGFONTW underline_font; + HFONT underline, old_font; + SCRIPT_ANALYSIS *ssa; + INT ret, count; + HFONT current; + SIZE size; + + if (!es->composition_text) + return 0; + count = wcslen(es->composition_text); + + ssa = EDIT_UpdateUniscribeData_composition(es, dc, count); + if (ssa) + { + ScriptStringOut(ssa, x, y, 0, &es->format_rect, 0, count, FALSE); + ScriptStringCPtoX(ssa, count - 1, TRUE, &ret); + return ret; + } + + current = GetCurrentObject(dc,OBJ_FONT); + GetObjectW(current,sizeof(LOGFONTW),&underline_font); + underline_font.lfUnderline = TRUE; + underline = CreateFontIndirectW(&underline_font); + old_font = SelectObject(dc,underline); + + if (es->style & ES_MULTILINE) { + ret = (INT)LOWORD(TabbedTextOutW(dc, x, y, es->composition_text, count, + es->tabs_count, es->tabs, es->format_rect.left - es->x_offset)); + } else { + TextOutW(dc, x, y, es->composition_text, count); + GetTextExtentPoint32W(dc, es->composition_text, count, &size); + ret = size.cx; + } + + if (old_font) + SelectObject(dc,old_font); + if (underline) + DeleteObject(underline); + + return ret; +} + /********************************************************************* * * EDIT_PaintText @@ -2052,9 +2120,6 @@ static INT EDIT_PaintText(EDITSTATE *es, HDC dc, INT x, INT y, INT line, INT col { COLORREF BkColor; COLORREF TextColor; - LOGFONTW underline_font; - HFONT hUnderline = 0; - HFONT old_font = 0; INT ret; INT li; INT BkMode; @@ -2066,20 +2131,9 @@ static INT EDIT_PaintText(EDITSTATE *es, HDC dc, INT x, INT y, INT line, INT col BkColor = GetBkColor(dc); TextColor = GetTextColor(dc); if (rev) { - if (es->composition_len == 0) - { - SetBkColor(dc, GetSysColor(COLOR_HIGHLIGHT)); - SetTextColor(dc, GetSysColor(COLOR_HIGHLIGHTTEXT)); - SetBkMode( dc, OPAQUE); - } - else - { - HFONT current = GetCurrentObject(dc,OBJ_FONT); - GetObjectW(current,sizeof(LOGFONTW),&underline_font); - underline_font.lfUnderline = TRUE; - hUnderline = CreateFontIndirectW(&underline_font); - old_font = SelectObject(dc,hUnderline); - } + SetBkColor(dc, GetSysColor(COLOR_HIGHLIGHT)); + SetTextColor(dc, GetSysColor(COLOR_HIGHLIGHTTEXT)); + SetBkMode( dc, OPAQUE); } li = EDIT_EM_LineIndex(es, line); if (es->style & ES_MULTILINE) { @@ -2091,19 +2145,9 @@ static INT EDIT_PaintText(EDITSTATE *es, HDC dc, INT x, INT y, INT line, INT col ret = size.cx; } if (rev) { - if (es->composition_len == 0) - { - SetBkColor(dc, BkColor); - SetTextColor(dc, TextColor); - SetBkMode( dc, BkMode); - } - else - { - if (old_font) - SelectObject(dc,old_font); - if (hUnderline) - DeleteObject(hUnderline); - } + SetBkColor(dc, BkColor); + SetTextColor(dc, TextColor); + SetBkMode( dc, BkMode); } return ret; } @@ -2116,6 +2160,7 @@ static INT EDIT_PaintText(EDITSTATE *es, HDC dc, INT x, INT y, INT line, INT col */ static void EDIT_PaintLine(EDITSTATE *es, HDC dc, INT line, BOOL rev) { + BOOL comp = FALSE; INT s = 0; INT e = 0; INT li = 0; @@ -2171,19 +2216,30 @@ static void EDIT_PaintLine(EDITSTATE *es, HDC dc, INT line, BOOL rev) ll = EDIT_EM_LineLength(es, li); s = min(es->selection_start, es->selection_end); e = max(es->selection_start, es->selection_end); + if (s >= li && s <= li + ll) comp = TRUE; s = min(li + ll, max(li, s)); e = min(li + ll, max(li, e)); }
if (ssa) + { ScriptStringOut(ssa, x, y, 0, &es->format_rect, s - li, e - li, FALSE); + ScriptStringCPtoX(ssa, s - li - 1, TRUE, &x); + if (comp) EDIT_PaintComposition(es, dc, x, y); + } else if (rev && (s != e) && ((es->flags & EF_FOCUSED) || (es->style & ES_NOHIDESEL))) { x += EDIT_PaintText(es, dc, x, y, line, 0, s - li, FALSE); + if (comp) x += EDIT_PaintComposition(es, dc, x, y); x += EDIT_PaintText(es, dc, x, y, line, s - li, e - s, TRUE); x += EDIT_PaintText(es, dc, x, y, line, e - li, li + ll - e, FALSE); - } else - x += EDIT_PaintText(es, dc, x, y, line, 0, ll, FALSE); + } + else + { + x += EDIT_PaintText(es, dc, x, y, line, 0, s - li, FALSE); + if (comp) x += EDIT_PaintComposition(es, dc, x, y); + x += EDIT_PaintText(es, dc, x, y, line, s - li, li + ll - s, FALSE); + }
if (es->cue_banner_text && es->text_length == 0 && (!(es->flags & EF_FOCUSED) || es->cue_banner_draw_focused)) { @@ -4258,14 +4314,21 @@ static void EDIT_GetCompositionStr(HIMC hIMC, LPARAM CompFlag, EDITSTATE *es) LPSTR lpCompStrAttr = NULL; DWORD dwBufLenAttr;
- buflen = ImmGetCompositionStringW(hIMC, GCS_COMPSTR, NULL, 0); + Free(es->composition_text); + es->composition_text = NULL; + if (es->composition_ssa) + { + ScriptStringFree(&es->composition_ssa); + es->composition_ssa = NULL; + }
+ buflen = ImmGetCompositionStringW(hIMC, GCS_COMPSTR, NULL, 0); if (buflen < 0) { return; }
- lpCompStr = Alloc(buflen); + lpCompStr = Alloc(buflen + sizeof(WCHAR)); if (!lpCompStr) { ERR("Unable to allocate IME CompositionString\n"); @@ -4298,26 +4361,11 @@ static void EDIT_GetCompositionStr(HIMC hIMC, LPARAM CompFlag, EDITSTATE *es) } }
- /* check for change in composition start */ - if (es->selection_end < es->composition_start) - es->composition_start = es->selection_end; - - /* replace existing selection string */ - es->selection_start = es->composition_start; - - if (es->composition_len > 0) - es->selection_end = es->composition_start + es->composition_len; - else - es->selection_end = es->selection_start; - - EDIT_EM_ReplaceSel(es, FALSE, lpCompStr, buflen / sizeof(WCHAR), TRUE, TRUE); - es->composition_len = abs(es->composition_start - es->selection_end); - - es->selection_start = es->composition_start; - es->selection_end = es->selection_start + es->composition_len; - Free(lpCompStrAttr); - Free(lpCompStr); + es->composition_text = lpCompStr; + + es->flags |= EF_UPDATE; + EDIT_UpdateText(es, NULL, TRUE); }
static void EDIT_GetResultStr(HIMC hIMC, EDITSTATE *es) @@ -4340,47 +4388,26 @@ static void EDIT_GetResultStr(HIMC hIMC, EDITSTATE *es)
ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, lpResultStr, buflen);
- /* check for change in composition start */ - if (es->selection_end < es->composition_start) - es->composition_start = es->selection_end; - - es->selection_start = es->composition_start; - es->selection_end = es->composition_start + es->composition_len; EDIT_EM_ReplaceSel(es, TRUE, lpResultStr, buflen / sizeof(WCHAR), TRUE, TRUE); - es->composition_start = es->selection_end; - es->composition_len = 0; - Free(lpResultStr); }
static void EDIT_ImeComposition(HWND hwnd, LPARAM CompFlag, EDITSTATE *es) { HIMC hIMC; - int cursor;
- if (es->composition_len == 0 && es->selection_start != es->selection_end) - { + if (!es->composition_text && es->selection_start != es->selection_end) EDIT_EM_ReplaceSel(es, TRUE, NULL, 0, TRUE, TRUE); - es->composition_start = es->selection_end; - }
hIMC = ImmGetContext(hwnd); if (!hIMC) return;
if (CompFlag & GCS_RESULTSTR) - { EDIT_GetResultStr(hIMC, es); - cursor = 0; - } - else - { - if (CompFlag & GCS_COMPSTR) - EDIT_GetCompositionStr(hIMC, CompFlag, es); - cursor = ImmGetCompositionStringW(hIMC, GCS_CURSORPOS, 0, 0); - } + else if (CompFlag & GCS_COMPSTR) + EDIT_GetCompositionStr(hIMC, CompFlag, es); ImmReleaseContext(hwnd, hIMC); - EDIT_SetCaretPos(es, es->selection_start + cursor, es->flags & EF_AFTER_WRAP); }
@@ -5051,8 +5078,6 @@ static LRESULT CALLBACK EDIT_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPAR break;
case WM_IME_STARTCOMPOSITION: - es->composition_start = es->selection_end; - es->composition_len = 0; break;
case WM_IME_COMPOSITION: @@ -5066,11 +5091,12 @@ static LRESULT CALLBACK EDIT_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPAR break;
case WM_IME_ENDCOMPOSITION: - if (es->composition_len > 0) + Free(es->composition_text); + es->composition_text = NULL; + if (es->composition_ssa) { - EDIT_EM_ReplaceSel(es, TRUE, NULL, 0, TRUE, TRUE); - es->selection_end = es->selection_start; - es->composition_len= 0; + ScriptStringFree(&es->composition_ssa); + es->composition_ssa = NULL; } break;
From: Rémi Bernon rbernon@codeweavers.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53860 --- dlls/user32/edit.c | 201 +++++++++++++++++++++++++-------------------- 1 file changed, 114 insertions(+), 87 deletions(-)
diff --git a/dlls/user32/edit.c b/dlls/user32/edit.c index 47c61f59c24..df9e184e408 100644 --- a/dlls/user32/edit.c +++ b/dlls/user32/edit.c @@ -128,8 +128,8 @@ typedef struct /* * IME Data */ - UINT composition_len; /* length of composition, 0 == no composition */ - int composition_start; /* the character position for the composition */ + LPWSTR composition_text; /* the contents of the composition string */ + SCRIPT_STRING_ANALYSIS composition_ssa; UINT ime_status; /* IME status flag */ /* * Uniscribe Data @@ -367,6 +367,30 @@ static inline void EDIT_InvalidateUniscribeData(EDITSTATE *es) } }
+static SCRIPT_STRING_ANALYSIS EDIT_UpdateUniscribeData_composition(EDITSTATE *es, HDC dc, INT length) +{ + if (!es->composition_ssa) + { + HFONT old_font = NULL; + HDC udc = dc; + + if (!udc) + udc = NtUserGetDC(es->hwndSelf); + if (es->font) + old_font = SelectObject(udc, es->font); + + ScriptStringAnalyse(udc, es->composition_text, length, (1.5*length+16), -1, SSA_LINK|SSA_FALLBACK|SSA_GLYPHS, + -1, NULL, NULL, NULL, NULL, NULL, &es->composition_ssa); + + if (es->font) + SelectObject(udc, old_font); + if (udc != dc) + NtUserReleaseDC(es->hwndSelf, udc); + } + + return es->composition_ssa; +} + static SCRIPT_STRING_ANALYSIS EDIT_UpdateUniscribeData_linedef(EDITSTATE *es, HDC dc, LINEDEF *line_def) { if (!line_def) @@ -2125,6 +2149,50 @@ static void EDIT_MoveWordForward(EDITSTATE *es, BOOL extend) }
+static INT EDIT_PaintComposition(EDITSTATE *es, HDC dc, INT x, INT y) +{ + LOGFONTW underline_font; + HFONT underline, old_font; + SCRIPT_ANALYSIS *ssa; + INT ret, count; + HFONT current; + SIZE size; + + if (!es->composition_text) + return 0; + count = wcslen(es->composition_text); + + ssa = EDIT_UpdateUniscribeData_composition(es, dc, count); + if (ssa) + { + ScriptStringOut(ssa, x, y, 0, &es->format_rect, 0, count, FALSE); + ScriptStringCPtoX(ssa, count - 1, TRUE, &ret); + return ret; + } + + current = GetCurrentObject(dc,OBJ_FONT); + GetObjectW(current,sizeof(LOGFONTW),&underline_font); + underline_font.lfUnderline = TRUE; + underline = CreateFontIndirectW(&underline_font); + old_font = SelectObject(dc,underline); + + if (es->style & ES_MULTILINE) { + ret = (INT)LOWORD(TabbedTextOutW(dc, x, y, es->composition_text, count, + es->tabs_count, es->tabs, es->format_rect.left - es->x_offset)); + } else { + TextOutW(dc, x, y, es->composition_text, count); + GetTextExtentPoint32W(dc, es->composition_text, count, &size); + ret = size.cx; + } + + if (old_font) + SelectObject(dc,old_font); + if (underline) + DeleteObject(underline); + + return ret; +} + /********************************************************************* * * EDIT_PaintText @@ -2134,9 +2202,6 @@ static INT EDIT_PaintText(EDITSTATE *es, HDC dc, INT x, INT y, INT line, INT col { COLORREF BkColor; COLORREF TextColor; - LOGFONTW underline_font; - HFONT hUnderline = 0; - HFONT old_font = 0; INT ret; INT li; INT BkMode; @@ -2148,20 +2213,9 @@ static INT EDIT_PaintText(EDITSTATE *es, HDC dc, INT x, INT y, INT line, INT col BkColor = GetBkColor(dc); TextColor = GetTextColor(dc); if (rev) { - if (es->composition_len == 0) - { - SetBkColor(dc, GetSysColor(COLOR_HIGHLIGHT)); - SetTextColor(dc, GetSysColor(COLOR_HIGHLIGHTTEXT)); - SetBkMode( dc, OPAQUE); - } - else - { - HFONT current = GetCurrentObject(dc,OBJ_FONT); - GetObjectW(current,sizeof(LOGFONTW),&underline_font); - underline_font.lfUnderline = TRUE; - hUnderline = CreateFontIndirectW(&underline_font); - old_font = SelectObject(dc,hUnderline); - } + SetBkColor(dc, GetSysColor(COLOR_HIGHLIGHT)); + SetTextColor(dc, GetSysColor(COLOR_HIGHLIGHTTEXT)); + SetBkMode( dc, OPAQUE); } li = EDIT_EM_LineIndex(es, line); if (es->style & ES_MULTILINE) { @@ -2173,19 +2227,9 @@ static INT EDIT_PaintText(EDITSTATE *es, HDC dc, INT x, INT y, INT line, INT col ret = size.cx; } if (rev) { - if (es->composition_len == 0) - { - SetBkColor(dc, BkColor); - SetTextColor(dc, TextColor); - SetBkMode( dc, BkMode); - } - else - { - if (old_font) - SelectObject(dc,old_font); - if (hUnderline) - DeleteObject(hUnderline); - } + SetBkColor(dc, BkColor); + SetTextColor(dc, TextColor); + SetBkMode( dc, BkMode); } return ret; } @@ -2198,6 +2242,7 @@ static INT EDIT_PaintText(EDITSTATE *es, HDC dc, INT x, INT y, INT line, INT col */ static void EDIT_PaintLine(EDITSTATE *es, HDC dc, INT line, BOOL rev) { + BOOL comp = FALSE; INT s = 0; INT e = 0; INT li = 0; @@ -2253,19 +2298,30 @@ static void EDIT_PaintLine(EDITSTATE *es, HDC dc, INT line, BOOL rev) ll = EDIT_EM_LineLength(es, li); s = min(es->selection_start, es->selection_end); e = max(es->selection_start, es->selection_end); + if (s >= li && s <= li + ll) comp = TRUE; s = min(li + ll, max(li, s)); e = min(li + ll, max(li, e)); }
if (ssa) + { ScriptStringOut(ssa, x, y, 0, &es->format_rect, s - li, e - li, FALSE); + ScriptStringCPtoX(ssa, s - li - 1, TRUE, &x); + if (comp) EDIT_PaintComposition(es, dc, x, y); + } else if (rev && (s != e) && ((es->flags & EF_FOCUSED) || (es->style & ES_NOHIDESEL))) { x += EDIT_PaintText(es, dc, x, y, line, 0, s - li, FALSE); + if (comp) x += EDIT_PaintComposition(es, dc, x, y); x += EDIT_PaintText(es, dc, x, y, line, s - li, e - s, TRUE); x += EDIT_PaintText(es, dc, x, y, line, e - li, li + ll - e, FALSE); - } else - x += EDIT_PaintText(es, dc, x, y, line, 0, ll, FALSE); + } + else + { + x += EDIT_PaintText(es, dc, x, y, line, 0, s - li, FALSE); + if (comp) x += EDIT_PaintComposition(es, dc, x, y); + x += EDIT_PaintText(es, dc, x, y, line, s - li, li + ll - s, FALSE); + } }
@@ -4343,6 +4399,14 @@ static void EDIT_GetCompositionStr(HIMC hIMC, LPARAM CompFlag, EDITSTATE *es) LPSTR lpCompStrAttr = NULL; DWORD dwBufLenAttr;
+ HeapFree(GetProcessHeap(), 0, es->composition_text); + es->composition_text = NULL; + if (es->composition_ssa) + { + ScriptStringFree(&es->composition_ssa); + es->composition_ssa = NULL; + } + buflen = ImmGetCompositionStringW(hIMC, GCS_COMPSTR, NULL, 0);
if (buflen < 0) @@ -4350,7 +4414,7 @@ static void EDIT_GetCompositionStr(HIMC hIMC, LPARAM CompFlag, EDITSTATE *es) return; }
- lpCompStr = HeapAlloc(GetProcessHeap(),0,buflen); + lpCompStr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buflen + sizeof(WCHAR)); if (!lpCompStr) { ERR("Unable to allocate IME CompositionString\n"); @@ -4383,26 +4447,11 @@ static void EDIT_GetCompositionStr(HIMC hIMC, LPARAM CompFlag, EDITSTATE *es) } }
- /* check for change in composition start */ - if (es->selection_end < es->composition_start) - es->composition_start = es->selection_end; - - /* replace existing selection string */ - es->selection_start = es->composition_start; - - if (es->composition_len > 0) - es->selection_end = es->composition_start + es->composition_len; - else - es->selection_end = es->selection_start; - - EDIT_EM_ReplaceSel(es, FALSE, lpCompStr, buflen / sizeof(WCHAR), TRUE, TRUE); - es->composition_len = abs(es->composition_start - es->selection_end); - - es->selection_start = es->composition_start; - es->selection_end = es->selection_start + es->composition_len; - HeapFree(GetProcessHeap(),0,lpCompStrAttr); - HeapFree(GetProcessHeap(),0,lpCompStr); + es->composition_text = lpCompStr; + + es->flags |= EF_UPDATE; + EDIT_UpdateText(es, NULL, TRUE); }
static void EDIT_GetResultStr(HIMC hIMC, EDITSTATE *es) @@ -4425,47 +4474,26 @@ static void EDIT_GetResultStr(HIMC hIMC, EDITSTATE *es)
ImmGetCompositionStringW(hIMC, GCS_RESULTSTR, lpResultStr, buflen);
- /* check for change in composition start */ - if (es->selection_end < es->composition_start) - es->composition_start = es->selection_end; - - es->selection_start = es->composition_start; - es->selection_end = es->composition_start + es->composition_len; EDIT_EM_ReplaceSel(es, TRUE, lpResultStr, buflen / sizeof(WCHAR), TRUE, TRUE); - es->composition_start = es->selection_end; - es->composition_len = 0; - HeapFree(GetProcessHeap(),0,lpResultStr); }
static void EDIT_ImeComposition(HWND hwnd, LPARAM CompFlag, EDITSTATE *es) { HIMC hIMC; - int cursor;
- if (es->composition_len == 0 && es->selection_start != es->selection_end) - { + if (!es->composition_text && es->selection_start != es->selection_end) EDIT_EM_ReplaceSel(es, TRUE, NULL, 0, TRUE, TRUE); - es->composition_start = es->selection_end; - }
hIMC = ImmGetContext(hwnd); if (!hIMC) return;
if (CompFlag & GCS_RESULTSTR) - { EDIT_GetResultStr(hIMC, es); - cursor = 0; - } - else - { - if (CompFlag & GCS_COMPSTR) - EDIT_GetCompositionStr(hIMC, CompFlag, es); - cursor = ImmGetCompositionStringW(hIMC, GCS_CURSORPOS, 0, 0); - } + else if (CompFlag & GCS_COMPSTR) + EDIT_GetCompositionStr(hIMC, CompFlag, es); ImmReleaseContext(hwnd, hIMC); - EDIT_SetCaretPos(es, es->selection_start + cursor, es->flags & EF_AFTER_WRAP); }
@@ -5201,8 +5229,6 @@ LRESULT EditWndProc_common( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, B break;
case WM_IME_STARTCOMPOSITION: - es->composition_start = es->selection_end; - es->composition_len = 0; break;
case WM_IME_COMPOSITION: @@ -5216,13 +5242,14 @@ LRESULT EditWndProc_common( HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam, B break;
case WM_IME_ENDCOMPOSITION: - if (es->composition_len > 0) - { - EDIT_EM_ReplaceSel(es, TRUE, NULL, 0, TRUE, TRUE); - es->selection_end = es->selection_start; - es->composition_len= 0; - } - break; + HeapFree(GetProcessHeap(), 0, es->composition_text); + es->composition_text = NULL; + if (es->composition_ssa) + { + ScriptStringFree(&es->composition_ssa); + es->composition_ssa = NULL; + } + break;
case WM_IME_COMPOSITIONFULL: break;
On Thu May 4 14:50:20 2023 +0000, Rémi Bernon wrote:
Right, it's duplicating the composition string on every line now, I'll fix this. I see that the cursor is also incorrectly moved too.
It should be working fine now, I dropped the cursor updates which are now meaningless as the composition string is separate from the text. We could perhaps consider adding a marker to the new display, depending on how critical it seems.
On Thu May 4 15:39:25 2023 +0000, Rémi Bernon wrote:
It should be working fine now, I dropped the cursor updates which are now meaningless as the composition string is separate from the text. We could perhaps consider adding a marker to the new display, depending on how critical it seems.
Thank you so much. It's working fine.
I found an issue with the "Wrap long lines" feature not working for ime composition string.
I think I will just move the drawing to imm32. As @bsjeon said, native edit control simply does that for the Japanese IME and there's actually not too much to fix there. Korean IME style is different but I suspect this is a matter of WM_IME_COMPOSITION CS_INSERTCHAR|CS_NOMOVECARET flags presence.
On Thu May 4 21:18:42 2023 +0000, Rémi Bernon wrote:
I think I will just move the drawing to imm32. As @bsjeon said, native edit control simply does that for the Japanese IME and there's actually not too much to fix there. Korean IME style is different but I suspect this is a matter of WM_IME_COMPOSITION CS_INSERTCHAR|CS_NOMOVECARET flags presence.
I absolutely agree. The attached image is an example of the Japanese IME UI Composition Window.
![japanese_multiline_ime_ui_composition_window](/uploads/79bf388a85dbb076aef7e1a518127124/japanese_multiline_ime_ui_composition_window.png)
This is one composition string, and the UI_HWND has 4 ui-composition child windows.
Do we need to do ScriptStringFree() on window destruction too? Like we do for main text. Otherwise I'm going to unassign myself, as I have no idea about IME behavior and I'm not using it.
Zhiyi Zhang (@zhiyi) commented about dlls/comctl32/edit.c:
- HFONT current;
- SIZE size;
- if (!es->composition_text)
return 0;
- count = wcslen(es->composition_text);
- ssa = EDIT_UpdateUniscribeData_composition(es, dc, count);
- if (ssa)
- {
ScriptStringOut(ssa, x, y, 0, &es->format_rect, 0, count, FALSE);
ScriptStringCPtoX(ssa, count - 1, TRUE, &ret);
return ret;
- }
- current = GetCurrentObject(dc,OBJ_FONT);
Formatting. Please put a space after the comma.
Zhiyi Zhang (@zhiyi) commented about dlls/comctl32/edit.c:
{
SetBkColor(dc, GetSysColor(COLOR_HIGHLIGHT));
SetTextColor(dc, GetSysColor(COLOR_HIGHLIGHTTEXT));
SetBkMode( dc, OPAQUE);
}
else
{
HFONT current = GetCurrentObject(dc,OBJ_FONT);
GetObjectW(current,sizeof(LOGFONTW),&underline_font);
underline_font.lfUnderline = TRUE;
hUnderline = CreateFontIndirectW(&underline_font);
old_font = SelectObject(dc,hUnderline);
}
SetBkColor(dc, GetSysColor(COLOR_HIGHLIGHT));
SetTextColor(dc, GetSysColor(COLOR_HIGHLIGHTTEXT));
SetBkMode( dc, OPAQUE);
The composition text is painted highlighted and this is not the case on Windows.
Zhiyi Zhang (@zhiyi) commented about dlls/comctl32/edit.c:
if (comp) EDIT_PaintComposition(es, dc, x, y);
- } else if (rev && (s != e) && ((es->flags & EF_FOCUSED) || (es->style & ES_NOHIDESEL))) { x += EDIT_PaintText(es, dc, x, y, line, 0, s - li, FALSE);
x += EDIT_PaintText(es, dc, x, y, line, s - li, e - s, TRUE); x += EDIT_PaintText(es, dc, x, y, line, e - li, li + ll - e, FALSE);if (comp) x += EDIT_PaintComposition(es, dc, x, y);
- } else
x += EDIT_PaintText(es, dc, x, y, line, 0, ll, FALSE);
- }
- else
- {
x += EDIT_PaintText(es, dc, x, y, line, 0, s - li, FALSE);
if (comp) x += EDIT_PaintComposition(es, dc, x, y);
x += EDIT_PaintText(es, dc, x, y, line, s - li, li + ll - s, FALSE);
The composition text doesn't paint across multiple lines. Could you do something about that?