[2/7] richedit: End of line sequence limited to 2 carriage returns.
Dylan Smith
dylan.ah.smith at gmail.com
Tue Jan 27 02:38:49 CST 2009
riched32.dll does preserve the carraige 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.
It is the \r\r\n sequence that is handled specially. For v1.0 this
becomes a line break, for v2.0+ this becomes a space.
The similarities between the version allow for a simpler version of the
ME_InsertTextFromCursor to be written. I chose to also get rid of
unnecessary continue statements, and considions that were always true,
since they made the function hard to read.
---
dlls/riched20/caret.c | 131 ++++++++++++++---------------------------
dlls/riched32/tests/editor.c | 27 ++------
2 files changed, 52 insertions(+), 106 deletions(-)
-------------- next part --------------
diff --git a/dlls/riched20/caret.c b/dlls/riched20/caret.c
index bd0b149..460f9be 100644
--- a/dlls/riched20/caret.c
+++ b/dlls/riched20/caret.c
@@ -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 */
- WCHAR tab = '\t';
- if (pos!=str)
- ME_InternalInsertTextFromCursor(editor, nCursor, str, pos-str, style, 0);
-
+ if (pos != str) { /* handle text */
+ ME_InternalInsertTextFromCursor(editor, nCursor, str, pos-str, style, 0);
+ } else if (*pos == '\t') { /* handle tabs */
+ WCHAR tab = '\t';
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;
-
- if(pos-str <= len) {
- len -= pos - str;
- str = pos;
- continue;
+ pos += numCR + numLF;
+
+ 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;
}
}
diff --git a/dlls/riched32/tests/editor.c b/dlls/riched32/tests/editor.c
index 1fab410..b01faee 100644
--- a/dlls/riched32/tests/editor.c
+++ b/dlls/riched32/tests/editor.c
@@ -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);
}
}
More information about the wine-patches
mailing list