Alex Villacís Lasso : richedit: Flip the big switch and encode actual CR and LF into end-of-paragraph runs .
Alexandre Julliard
julliard at winehq.org
Tue Apr 29 08:54:47 CDT 2008
Module: wine
Branch: master
Commit: 4047df0f564786437cdf9a0712fbee603f5f3d2f
URL: http://source.winehq.org/git/wine.git/?a=commit;h=4047df0f564786437cdf9a0712fbee603f5f3d2f
Author: Alex Villacís Lasso <a_villacis at 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);
}
More information about the wine-cvs
mailing list