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:
Dylan Smith 2009-01-27 03:38:49 -05:00 committed by Alexandre Julliard
parent 29ddbce288
commit 0832737427
2 changed files with 51 additions and 105 deletions

View file

@ -517,107 +517,66 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor,
if(editor->nTextLimit < oldLen +len)
editor->nTextLimit = oldLen + len;
pos = str;
while (len)
{
pos = str;
/* 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++;
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';
if (pos!=str)
ME_InternalInsertTextFromCursor(editor, nCursor, str, pos-str, style, 0);
ME_InternalInsertTextFromCursor(editor, nCursor, &tab, 1, style, MERF_TAB);
pos++;
if(pos-str <= len) {
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 */
} else { /* handle EOLs */
ME_DisplayItem *tp, *end_run;
ME_Style *tmp_style;
int numCR, numLF;
if (pos!=str)
ME_InternalInsertTextFromCursor(editor, nCursor, str, pos-str, style, 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 */
/* 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;
}
/* Find number of CR and LF in end of paragraph run */
numCR = 0; numLF = 0;
if (*pos =='\r')
{
numCR++;
if (len > 1 && pos[1] == '\n')
numLF++;
else if (len > 2 && pos[1] == '\r' && pos[2] == '\n')
numCR++, numLF++;
} else {
if(pos-str < len && *pos =='\r')
pos++;
if(pos-str < len && *pos =='\n')
pos++;
numCR = 1; numLF = 0;
assert(*pos == '\n');
numLF++;
}
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;
pos += numCR + numLF;
if(pos-str <= len) {
len -= pos - str;
str = pos;
continue;
if (!editor->bEmulateVersion10 && numCR == 2 && numLF == 1)
{
/* handle special \r\r\n sequence (richedit 2.x and higher only) */
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 = 0;
len -= pos - str;
str = pos;
}
}

View file

@ -392,12 +392,8 @@ static void test_EM_GETLINE(void)
/* EM_GETLINE appends a "\r\0" to the end of the line
* nCopied counts up to and including the '\r' */
nCopied = SendMessage(hwndRichEdit, EM_GETLINE, gl[i].line, (LPARAM) dest);
if (i >= 1 && i <= 4)
todo_wine ok(nCopied == expected_nCopied, "%d: %d!=%d\n", i, nCopied,
expected_nCopied);
else
ok(nCopied == expected_nCopied, "%d: %d!=%d\n", i, nCopied,
expected_nCopied);
ok(nCopied == expected_nCopied, "%d: %d!=%d\n", i, nCopied,
expected_nCopied);
/* two special cases since a parameter is passed via dest */
if (gl[i].buffer_len == 0)
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");
else
{
if (i >= 1 && i <= 4)
todo_wine ok(!strncmp(dest, gl[i].text, expected_bytes_written),
"%d: expected_bytes_written=%d\n", i, expected_bytes_written);
else
ok(!strncmp(dest, gl[i].text, 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);
ok(!strncmp(dest, gl[i].text, expected_bytes_written),
"%d: expected_bytes_written=%d\n", i, expected_bytes_written);
ok(!strncmp(dest + expected_bytes_written, origdest
+ expected_bytes_written, nBuf - expected_bytes_written),
"%d: expected_bytes_written=%d\n", i, expected_bytes_written);
}
}