Module: wine Branch: master Commit: 4047df0f564786437cdf9a0712fbee603f5f3d2f URL: http://source.winehq.org/git/wine.git/?a=commit;h=4047df0f564786437cdf9a0712...
Author: Alex Villacís Lasso a_villacis@palosanto.com Date: Sat Apr 26 22:49:35 2008 -0500
richedit: Flip the big switch and encode actual CR and LF into end-of-paragraph runs.
Document remaining uses of bEmulateVersion10 and other checks for CRLF in editor.c. Make RTF reader emit a \r or a \r\n according to emulation, not a \n, which breaks streaming tests. Remove todo_wine from a bunch of riched32 tests that now succeed.
---
dlls/riched20/caret.c | 43 ++++++++++++++++++++++++++--------------- dlls/riched20/editor.c | 26 +++++++++++++++++++++++- dlls/riched20/reader.c | 3 +- dlls/riched32/tests/editor.c | 34 ++++++++++++++++---------------- 4 files changed, 70 insertions(+), 36 deletions(-)
diff --git a/dlls/riched20/caret.c b/dlls/riched20/caret.c index a8e51db..bf53aff 100644 --- a/dlls/riched20/caret.c +++ b/dlls/riched20/caret.c @@ -524,6 +524,8 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, if (pos-str < len) { /* 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]; @@ -534,38 +536,47 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor, tmp_style = ME_GetInsertStyle(editor, nCursor); /* ME_SplitParagraph increases style refcount */
- /* TODO: move here and fix logic for pos updating according to emulation, - so that number of CR and LF encoded are a result of such logic, instead - of hardcoded as below. - */ - if (editor->bEmulateVersion10) - tp = ME_SplitParagraph(editor, p->pRun, p->pRun->member.run.style, 1, 1); - else - tp = ME_SplitParagraph(editor, p->pRun, p->pRun->member.run.style, 1, 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; + /* 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) { - if (tpos != pos) pos++; - } else if (*tpos == '\n') + /* 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; - else + numLF = 1; + } else { + /* Found some other content past the run of \r's */ pos++; + numCR = 1; numLF = 0; + } } else { if(pos-str < len && *pos =='\r') pos++; if(pos-str < len && *pos =='\n') pos++; + numCR = 1; numLF = 0; } + tp = ME_SplitParagraph(editor, p->pRun, p->pRun->member.run.style, 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) { len -= pos - str; str = pos; diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c index d0d6195..4b4db9f 100644 --- a/dlls/riched20/editor.c +++ b/dlls/riched20/editor.c @@ -1101,7 +1101,10 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre if (parser.lpRichEditOle) IRichEditOle_Release(parser.lpRichEditOle);
- /* Remove last line break, as mandated by tests */ + /* Remove last line break, as mandated by tests. This is not affected by + CR/LF counters, since RTF streaming presents only \para tokens, which + are converted according to the standard rules: \r for 2.0, \r\n for 1.0 + */ if (stripLastCR) { int newfrom, newto; ME_GetSelection(editor, &newfrom, &newto); @@ -1213,6 +1216,21 @@ ME_FindItemAtOffset(ME_TextEditor *editor, ME_DIType nItemType, int nOffset, int } while (item && (item->member.run.nCharOfs + runLength <= nOffset)); if (item) { nOffset -= item->member.run.nCharOfs; + + /* Special case: nOffset may not point exactly at the division between the + \r and the \n in 1.0 emulation. If such a case happens, it is sent + into the next run, if one exists + */ + if ( item->member.run.nFlags & MERF_ENDPARA + && nOffset == item->member.run.nCR + && item->member.run.nLF > 0) { + ME_DisplayItem *nextItem; + nextItem = ME_FindItemFwd(item, diRun); + if (nextItem) { + nOffset = 0; + item = nextItem; + } + } if (nItemOffset) *nItemOffset = nOffset; } @@ -2487,6 +2505,7 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam, { GETTEXTLENGTHEX how;
+ /* CR/LF conversion required in 2.0 mode, verbatim in 1.0 mode */ how.flags = GTL_CLOSE | (editor->bEmulateVersion10 ? 0 : GTL_USECRLF) | GTL_NUMCHARS; how.codepage = unicode ? 1200 : CP_ACP; return ME_GetTextLengthEx(editor, &how); @@ -2552,7 +2571,10 @@ static LRESULT RichEditWndProc_common(HWND hWnd, UINT msg, WPARAM wParam, else { /* potentially each char may be a CR, why calculate the exact value with O(N) when - we can just take a bigger buffer? :) */ + we can just take a bigger buffer? :) + The above assumption still holds with CR/LF counters, since CR->CRLF expansion + occurs only in richedit 2.0 mode, in which line breaks have only one CR + */ int crlfmul = (ex->flags & GT_USECRLF) ? 2 : 1; LPWSTR buffer; DWORD buflen = ex->cb; diff --git a/dlls/riched20/reader.c b/dlls/riched20/reader.c index 1ecca08..5ee9fa2 100644 --- a/dlls/riched20/reader.c +++ b/dlls/riched20/reader.c @@ -2605,7 +2605,8 @@ static void SpecialChar (RTF_Info *info) case rtfSect: case rtfRow: case rtfPar: - RTFPutUnicodeChar (info, '\n'); + RTFPutUnicodeChar (info, '\r'); + if (info->editor->bEmulateVersion10) RTFPutUnicodeChar (info, '\n'); break; case rtfNoBrkSpace: RTFPutUnicodeChar (info, 0x00A0); diff --git a/dlls/riched32/tests/editor.c b/dlls/riched32/tests/editor.c index 21972ab..70d1558 100644 --- a/dlls/riched32/tests/editor.c +++ b/dlls/riched32/tests/editor.c @@ -110,21 +110,21 @@ static void test_WM_SETTEXT() }
TEST_SETTEXT(TestItem1, TestItem1, 1, 0, 0) - TEST_SETTEXT(TestItem2, TestItem2, 1, 1, 1) - TEST_SETTEXT(TestItem3, TestItem3, 2, 1, 1) - TEST_SETTEXT(TestItem4, TestItem4, 3, 1, 0) - TEST_SETTEXT(TestItem5, TestItem5, 2, 1, 0) - TEST_SETTEXT(TestItem6, TestItem6, 3, 1, 0) - TEST_SETTEXT(TestItem7, TestItem7, 4, 1, 0) + TEST_SETTEXT(TestItem2, TestItem2, 1, 0, 1) + TEST_SETTEXT(TestItem3, TestItem3, 2, 0, 1) + TEST_SETTEXT(TestItem4, TestItem4, 3, 0, 0) + TEST_SETTEXT(TestItem5, TestItem5, 2, 0, 0) + TEST_SETTEXT(TestItem6, TestItem6, 3, 0, 0) + TEST_SETTEXT(TestItem7, TestItem7, 4, 0, 0) TEST_SETTEXT(TestItem8, TestItem8, 2, 0, 0) TEST_SETTEXT(TestItem9, TestItem9, 3, 0, 0) TEST_SETTEXT(TestItem10, TestItem10, 3, 0, 0) TEST_SETTEXT(TestItem11, TestItem11, 1, 0, 0) TEST_SETTEXT(TestItem12, TestItem12, 2, 0, 0) TEST_SETTEXT(TestItem13, TestItem13, 3, 0, 0) - TEST_SETTEXT(TestItem14, TestItem14, 2, 1, 0) - TEST_SETTEXT(TestItem15, TestItem15, 3, 1, 1) - TEST_SETTEXT(TestItem16, TestItem16, 4, 1, 0) + TEST_SETTEXT(TestItem14, TestItem14, 2, 0, 0) + TEST_SETTEXT(TestItem15, TestItem15, 3, 0, 1) + TEST_SETTEXT(TestItem16, TestItem16, 4, 0, 0)
#undef TEST_SETTEXT DestroyWindow(hwndRichEdit); @@ -332,11 +332,11 @@ static void test_EM_STREAMOUT(void) SendMessage(hwndRichEdit, EM_STREAMOUT, (WPARAM)(SF_TEXT), (LPARAM)&es); r = strlen(buf); - todo_wine { /* Currently fails because of solitary \r mangling */ + ok(r == 13, "streamed text length is %d, expecting 13\n", r); ok(strcmp(buf, TestItem2) == 0, "streamed text different, got %s\n", buf); - } + SendMessage(hwndRichEdit, WM_SETTEXT, 0, (LPARAM) TestItem3); p = buf; es.dwCookie = (DWORD_PTR)&p; @@ -360,8 +360,8 @@ static const struct getline_s { int wine_todo; } gl[] = { {0, 10, "foo bar\r\n", 0}, - {1, 10, "\n", 1}, - {2, 10, "bar\n", 1}, + {1, 10, "\n", 0}, + {2, 10, "bar\n", 0}, {3, 10, "\r\n", 0},
/* Buffer smaller than line length */ @@ -493,9 +493,9 @@ static void test_EM_GETTEXTRANGE(void) result = SendMessage(hwndRichEdit, EM_GETTEXTRANGE, 0, (LPARAM)&textRange); ok(result == 7, "EM_GETTEXTRANGE returned %ld, expected %d\n", result, strlen(expect2)); - todo_wine { + ok(!strcmp(expect2, buffer), "EM_GETTEXTRANGE filled %s\n", buffer); - } +
DestroyWindow(hwndRichEdit); } @@ -524,9 +524,9 @@ static void test_EM_GETSELTEXT(void) result = SendMessage(hwndRichEdit, EM_GETSELTEXT, 0, (LPARAM)buffer); ok(result == 7, "EM_GETTEXTRANGE returned %ld, expected %d\n", result, strlen(expect2)); - todo_wine { + ok(!strcmp(expect2, buffer), "EM_GETTEXTRANGE filled %s\n", buffer); - } +
DestroyWindow(hwndRichEdit); }