user32: Use uniscribe ScriptBreak to handle edit control linebreaking.

This commit is contained in:
Aric Stewart 2011-10-10 14:54:41 -05:00 committed by Alexandre Julliard
parent ef5f3c1676
commit de8a059d52
2 changed files with 58 additions and 59 deletions

View File

@ -2,7 +2,7 @@ EXTRADEFS = -D_USER32_ -D_WINABLE_
MODULE = user32.dll MODULE = user32.dll
IMPORTLIB = user32 IMPORTLIB = user32
IMPORTS = gdi32 version advapi32 IMPORTS = gdi32 version advapi32
DELAYIMPORTS = imm32 DELAYIMPORTS = imm32 usp10
C_SRCS = \ C_SRCS = \
button.c \ button.c \

View File

@ -53,6 +53,7 @@
#include "winnt.h" #include "winnt.h"
#include "win.h" #include "win.h"
#include "imm.h" #include "imm.h"
#include "usp10.h"
#include "wine/unicode.h" #include "wine/unicode.h"
#include "controls.h" #include "controls.h"
#include "user_private.h" #include "user_private.h"
@ -153,6 +154,10 @@ typedef struct
*/ */
UINT composition_len; /* length of composition, 0 == no composition */ UINT composition_len; /* length of composition, 0 == no composition */
int composition_start; /* the character position for the composition */ int composition_start; /* the character position for the composition */
/*
* Uniscribe Data
*/
SCRIPT_LOGATTR *logAttr;
} EDITSTATE; } EDITSTATE;
@ -247,6 +252,14 @@ static HBRUSH EDIT_NotifyCtlColor(EDITSTATE *es, HDC hdc)
} }
static inline UINT get_text_length(EDITSTATE *es)
{
if(es->text_length == (UINT)-1)
es->text_length = strlenW(es->text);
return es->text_length;
}
/********************************************************************* /*********************************************************************
* *
* EDIT_WordBreakProc * EDIT_WordBreakProc
@ -256,61 +269,51 @@ static HBRUSH EDIT_NotifyCtlColor(EDITSTATE *es, HDC hdc)
* allows to be called without linebreaks between s[0] up to * allows to be called without linebreaks between s[0] up to
* s[count - 1]. Remember it is only called * s[count - 1]. Remember it is only called
* internally, so we can decide this for ourselves. * internally, so we can decide this for ourselves.
* Additional we will always be breaking the full string.
* *
*/ */
static INT EDIT_WordBreakProc(LPWSTR s, INT index, INT count, INT action) static INT EDIT_WordBreakProc(EDITSTATE *es, LPWSTR s, INT index, INT count, INT action)
{ {
INT ret = 0; INT ret = 0;
TRACE("s=%p, index=%d, count=%d, action=%d\n", s, index, count, action); TRACE("s=%p, index=%d, count=%d, action=%d\n", s, index, count, action);
if(!s) return 0; if(!s) return 0;
switch (action) { if (!es->logAttr)
case WB_LEFT: {
if (!count) SCRIPT_ANALYSIS psa;
break;
if (index) memset(&psa,0,sizeof(SCRIPT_ANALYSIS));
index--; psa.eScript = SCRIPT_UNDEFINED;
if (s[index] == ' ') {
while (index && (s[index] == ' ')) es->logAttr = HeapAlloc(GetProcessHeap(), 0, sizeof(SCRIPT_LOGATTR) * get_text_length(es));
index--; ScriptBreak(es->text, get_text_length(es), &psa, es->logAttr);
if (index) { }
while (index && (s[index] != ' '))
index--; switch (action) {
if (s[index] == ' ') case WB_LEFT:
index++; if (index)
} index--;
} else { while (index && !es->logAttr[index].fSoftBreak)
while (index && (s[index] != ' ')) index--;
index--; ret = index;
if (s[index] == ' ') break;
index++; case WB_RIGHT:
} if (!count)
ret = index; break;
break; while (s[index] && index < count && !es->logAttr[index].fSoftBreak)
case WB_RIGHT: index++;
if (!count) ret = index;
break; break;
if (index) case WB_ISDELIMITER:
index--; ret = es->logAttr[index].fWhiteSpace;
if (s[index] == ' ') break;
while ((index < count) && (s[index] == ' ')) index++; default:
else { ERR("unknown action code, please report !\n");
while (s[index] && (s[index] != ' ') && (index < count)) break;
index++; }
while ((s[index] == ' ') && (index < count)) index++; return ret;
}
ret = index;
break;
case WB_ISDELIMITER:
ret = (s[index] == ' ');
break;
default:
ERR("unknown action code, please report !\n");
break;
}
return ret;
} }
@ -357,7 +360,7 @@ static INT EDIT_CallWordBreakProc(EDITSTATE *es, INT start, INT index, INT count
} }
} }
else else
ret = EDIT_WordBreakProc(es->text + start, index, count, action); ret = EDIT_WordBreakProc(es, es->text, index+start, count+start, action) - start;
return ret; return ret;
} }
@ -642,14 +645,6 @@ static void EDIT_BuildLineDefs_ML(EDITSTATE *es, INT istart, INT iend, INT delta
ReleaseDC(es->hwndSelf, dc); ReleaseDC(es->hwndSelf, dc);
} }
static inline UINT get_text_length(EDITSTATE *es)
{
if(es->text_length == (UINT)-1)
es->text_length = strlenW(es->text);
return es->text_length;
}
/********************************************************************* /*********************************************************************
* *
* EDIT_GetPasswordPointer_SL * EDIT_GetPasswordPointer_SL
@ -1086,6 +1081,9 @@ static void EDIT_GetLineRect(EDITSTATE *es, INT line, INT scol, INT ecol, LPRECT
static inline void text_buffer_changed(EDITSTATE *es) static inline void text_buffer_changed(EDITSTATE *es)
{ {
es->text_length = (UINT)-1; es->text_length = (UINT)-1;
HeapFree( GetProcessHeap(), 0, es->logAttr );
es->logAttr = NULL;
} }
/********************************************************************* /*********************************************************************
@ -4318,6 +4316,7 @@ cleanup:
HeapFree(GetProcessHeap(), 0, es->first_line_def); HeapFree(GetProcessHeap(), 0, es->first_line_def);
HeapFree(GetProcessHeap(), 0, es->undo_text); HeapFree(GetProcessHeap(), 0, es->undo_text);
if (es->hloc32W) LocalFree(es->hloc32W); if (es->hloc32W) LocalFree(es->hloc32W);
HeapFree(GetProcessHeap(), 0, es->logAttr);
HeapFree(GetProcessHeap(), 0, es); HeapFree(GetProcessHeap(), 0, es);
return FALSE; return FALSE;
} }