richedit: End of line sequence limited to 2 carriage returns.
riched32.dll does preserve the carriage returns and line feeds unlike later versions of the richedit control, however the tests previously missed the fact that a sequence of carriage returns followed by a line feed (e.g. \r\r\r\n) can actually cause multiple paragraph breaks.
This commit is contained in:
parent
29ddbce288
commit
0832737427
|
@ -517,107 +517,66 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor,
|
||||||
if(editor->nTextLimit < oldLen +len)
|
if(editor->nTextLimit < oldLen +len)
|
||||||
editor->nTextLimit = oldLen + len;
|
editor->nTextLimit = oldLen + len;
|
||||||
|
|
||||||
|
pos = str;
|
||||||
|
|
||||||
while (len)
|
while (len)
|
||||||
{
|
{
|
||||||
pos = str;
|
|
||||||
/* FIXME this sucks - no respect for unicode (what else can be a line separator in unicode?) */
|
/* FIXME this sucks - no respect for unicode (what else can be a line separator in unicode?) */
|
||||||
while(pos-str < len && *pos != '\r' && *pos != '\n' && *pos != '\t')
|
while(pos - str < len && *pos != '\r' && *pos != '\n' && *pos != '\t')
|
||||||
pos++;
|
pos++;
|
||||||
if (pos-str < len && *pos == '\t') { /* handle tabs */
|
|
||||||
|
if (pos != str) { /* handle text */
|
||||||
|
ME_InternalInsertTextFromCursor(editor, nCursor, str, pos-str, style, 0);
|
||||||
|
} else if (*pos == '\t') { /* handle tabs */
|
||||||
WCHAR tab = '\t';
|
WCHAR tab = '\t';
|
||||||
|
|
||||||
if (pos!=str)
|
|
||||||
ME_InternalInsertTextFromCursor(editor, nCursor, str, pos-str, style, 0);
|
|
||||||
|
|
||||||
ME_InternalInsertTextFromCursor(editor, nCursor, &tab, 1, style, MERF_TAB);
|
ME_InternalInsertTextFromCursor(editor, nCursor, &tab, 1, style, MERF_TAB);
|
||||||
|
|
||||||
pos++;
|
pos++;
|
||||||
if(pos-str <= len) {
|
} else { /* handle EOLs */
|
||||||
len -= pos - str;
|
|
||||||
str = pos;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* handle special \r\r\n sequence (richedit 2.x and higher only) */
|
|
||||||
if (!editor->bEmulateVersion10 && pos-str < len-2 && pos[0] == '\r' && pos[1] == '\r' && pos[2] == '\n') {
|
|
||||||
WCHAR space = ' ';
|
|
||||||
|
|
||||||
if (pos!=str)
|
|
||||||
ME_InternalInsertTextFromCursor(editor, nCursor, str, pos-str, style, 0);
|
|
||||||
|
|
||||||
ME_InternalInsertTextFromCursor(editor, nCursor, &space, 1, style, 0);
|
|
||||||
|
|
||||||
pos+=3;
|
|
||||||
if(pos-str <= len) {
|
|
||||||
len -= pos - str;
|
|
||||||
str = pos;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pos-str < len) { /* handle EOLs */
|
|
||||||
ME_DisplayItem *tp, *end_run;
|
ME_DisplayItem *tp, *end_run;
|
||||||
ME_Style *tmp_style;
|
ME_Style *tmp_style;
|
||||||
int numCR, numLF;
|
int numCR, numLF;
|
||||||
|
|
||||||
if (pos!=str)
|
/* Find number of CR and LF in end of paragraph run */
|
||||||
ME_InternalInsertTextFromCursor(editor, nCursor, str, pos-str, style, 0);
|
numCR = 0; numLF = 0;
|
||||||
p = &editor->pCursors[nCursor];
|
if (*pos =='\r')
|
||||||
if (p->nOffset) {
|
{
|
||||||
ME_SplitRunSimple(editor, p->pRun, p->nOffset);
|
numCR++;
|
||||||
p = &editor->pCursors[nCursor];
|
if (len > 1 && pos[1] == '\n')
|
||||||
}
|
numLF++;
|
||||||
tmp_style = ME_GetInsertStyle(editor, nCursor);
|
else if (len > 2 && pos[1] == '\r' && pos[2] == '\n')
|
||||||
/* ME_SplitParagraph increases style refcount */
|
numCR++, numLF++;
|
||||||
|
|
||||||
/* Encode and fill number of CR and LF according to emulation mode */
|
|
||||||
if (editor->bEmulateVersion10) {
|
|
||||||
const WCHAR * tpos;
|
|
||||||
|
|
||||||
/* We have to find out how many consecutive \r are there, and if there
|
|
||||||
is a \n terminating the run of \r's. */
|
|
||||||
numCR = 0; numLF = 0;
|
|
||||||
tpos = pos;
|
|
||||||
while (tpos-str < len && *tpos == '\r') {
|
|
||||||
tpos++;
|
|
||||||
numCR++;
|
|
||||||
}
|
|
||||||
if (tpos-str >= len) {
|
|
||||||
/* Reached end of text without finding anything but '\r' */
|
|
||||||
if (tpos != pos) {
|
|
||||||
pos++;
|
|
||||||
}
|
|
||||||
numCR = 1; numLF = 0;
|
|
||||||
} else if (*tpos == '\n') {
|
|
||||||
/* The entire run of \r's plus the one \n is one single line break */
|
|
||||||
pos = tpos + 1;
|
|
||||||
numLF = 1;
|
|
||||||
} else {
|
|
||||||
/* Found some other content past the run of \r's */
|
|
||||||
pos++;
|
|
||||||
numCR = 1; numLF = 0;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if(pos-str < len && *pos =='\r')
|
assert(*pos == '\n');
|
||||||
pos++;
|
numLF++;
|
||||||
if(pos-str < len && *pos =='\n')
|
|
||||||
pos++;
|
|
||||||
numCR = 1; numLF = 0;
|
|
||||||
}
|
}
|
||||||
tp = ME_SplitParagraph(editor, p->pRun, p->pRun->member.run.style, numCR, numLF, 0);
|
pos += numCR + numLF;
|
||||||
p->pRun = ME_FindItemFwd(tp, diRun);
|
|
||||||
end_run = ME_FindItemBack(tp, diRun);
|
|
||||||
ME_ReleaseStyle(end_run->member.run.style);
|
|
||||||
end_run->member.run.style = tmp_style;
|
|
||||||
p->nOffset = 0;
|
|
||||||
|
|
||||||
if(pos-str <= len) {
|
if (!editor->bEmulateVersion10 && numCR == 2 && numLF == 1)
|
||||||
len -= pos - str;
|
{
|
||||||
str = pos;
|
/* handle special \r\r\n sequence (richedit 2.x and higher only) */
|
||||||
continue;
|
WCHAR space = ' ';
|
||||||
|
ME_InternalInsertTextFromCursor(editor, nCursor, &space, 1, style, 0);
|
||||||
|
} else {
|
||||||
|
if (!editor->bEmulateVersion10)
|
||||||
|
numCR = 1, numLF = 0;
|
||||||
|
|
||||||
|
p = &editor->pCursors[nCursor];
|
||||||
|
if (p->nOffset) {
|
||||||
|
ME_SplitRunSimple(editor, p->pRun, p->nOffset);
|
||||||
|
p = &editor->pCursors[nCursor];
|
||||||
|
}
|
||||||
|
tmp_style = ME_GetInsertStyle(editor, nCursor);
|
||||||
|
/* ME_SplitParagraph increases style refcount */
|
||||||
|
tp = ME_SplitParagraph(editor, p->pRun, p->pRun->member.run.style, numCR, numLF, 0);
|
||||||
|
p->pRun = ME_FindItemFwd(tp, diRun);
|
||||||
|
end_run = ME_FindItemBack(tp, diRun);
|
||||||
|
ME_ReleaseStyle(end_run->member.run.style);
|
||||||
|
end_run->member.run.style = tmp_style;
|
||||||
|
p->nOffset = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ME_InternalInsertTextFromCursor(editor, nCursor, str, len, style, 0);
|
len -= pos - str;
|
||||||
len = 0;
|
str = pos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -392,12 +392,8 @@ static void test_EM_GETLINE(void)
|
||||||
/* EM_GETLINE appends a "\r\0" to the end of the line
|
/* EM_GETLINE appends a "\r\0" to the end of the line
|
||||||
* nCopied counts up to and including the '\r' */
|
* nCopied counts up to and including the '\r' */
|
||||||
nCopied = SendMessage(hwndRichEdit, EM_GETLINE, gl[i].line, (LPARAM) dest);
|
nCopied = SendMessage(hwndRichEdit, EM_GETLINE, gl[i].line, (LPARAM) dest);
|
||||||
if (i >= 1 && i <= 4)
|
ok(nCopied == expected_nCopied, "%d: %d!=%d\n", i, nCopied,
|
||||||
todo_wine ok(nCopied == expected_nCopied, "%d: %d!=%d\n", i, nCopied,
|
expected_nCopied);
|
||||||
expected_nCopied);
|
|
||||||
else
|
|
||||||
ok(nCopied == expected_nCopied, "%d: %d!=%d\n", i, nCopied,
|
|
||||||
expected_nCopied);
|
|
||||||
/* two special cases since a parameter is passed via dest */
|
/* two special cases since a parameter is passed via dest */
|
||||||
if (gl[i].buffer_len == 0)
|
if (gl[i].buffer_len == 0)
|
||||||
ok(!dest[0] && !dest[1] && !strncmp(dest+2, origdest+2, nBuf-2),
|
ok(!dest[0] && !dest[1] && !strncmp(dest+2, origdest+2, nBuf-2),
|
||||||
|
@ -407,20 +403,11 @@ static void test_EM_GETLINE(void)
|
||||||
!strncmp(dest+2, origdest+2, nBuf-2), "buffer_len=1\n");
|
!strncmp(dest+2, origdest+2, nBuf-2), "buffer_len=1\n");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (i >= 1 && i <= 4)
|
ok(!strncmp(dest, gl[i].text, expected_bytes_written),
|
||||||
todo_wine ok(!strncmp(dest, gl[i].text, expected_bytes_written),
|
"%d: expected_bytes_written=%d\n", i, expected_bytes_written);
|
||||||
"%d: expected_bytes_written=%d\n", i, expected_bytes_written);
|
ok(!strncmp(dest + expected_bytes_written, origdest
|
||||||
else
|
+ expected_bytes_written, nBuf - expected_bytes_written),
|
||||||
ok(!strncmp(dest, gl[i].text, expected_bytes_written),
|
"%d: expected_bytes_written=%d\n", i, expected_bytes_written);
|
||||||
"%d: expected_bytes_written=%d\n", i, expected_bytes_written);
|
|
||||||
if (i >= 1 && i <= 2)
|
|
||||||
todo_wine ok(!strncmp(dest + expected_bytes_written, origdest
|
|
||||||
+ expected_bytes_written, nBuf - expected_bytes_written),
|
|
||||||
"%d: expected_bytes_written=%d\n", i, expected_bytes_written);
|
|
||||||
else
|
|
||||||
ok(!strncmp(dest + expected_bytes_written, origdest
|
|
||||||
+ expected_bytes_written, nBuf - expected_bytes_written),
|
|
||||||
"%d: expected_bytes_written=%d\n", i, expected_bytes_written);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue