Module: wine Branch: master Commit: 083273742750e800b9d86ddf5d5ebc5cd14a5d3b URL: http://source.winehq.org/git/wine.git/?a=commit;h=083273742750e800b9d86ddf5d...
Author: Dylan Smith dylan.ah.smith@gmail.com Date: Tue Jan 27 03:38:49 2009 -0500
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.
---
dlls/riched20/caret.c | 131 ++++++++++++++--------------------------- dlls/riched32/tests/editor.c | 27 ++------ 2 files changed, 52 insertions(+), 106 deletions(-)
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); } }