From 60725dc6bbc752f9b8301173d94fb3bc0aa632db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9=20van=20Geldorp?= Date: Sat, 8 Oct 2005 17:17:27 +0000 Subject: [PATCH] Sync to Wine-20050930: Rein Klazes - When scrolling, first update the new position of the control before calling UpdateWindow(). Alexandre Julliard - Fixed gcc 4.0 warnings. - We are no longer generating .dbg.c files. Krzysztof Foltman - Reimplementation of EM_LINELENGTH. - Some attempt at documentation of double-linked list of ME_DisplayItem's. - Optional destinations in stylesheets are now skipped properly (and not treated as the "proper" styles as they were before). - EOF condition in the middle of the stylesheet is no longer putting the reader into infinite loop, - Half-full input buffers don't trigger EOF anymore (although it could, in theory, break some apps, I find it unlikely - and the change makes Out from Boneville installer display license properly). Marcus Meissner - The last argument to MultiByteToWideChar is wide character count and not the buffer size in bytes. Fixed all places where it was wrong. svn path=/trunk/; revision=18345 --- reactos/lib/riched20/editor.c | 47 +++++++++++----------- reactos/lib/riched20/editor.h | 2 +- reactos/lib/riched20/editstr.h | 14 ++++++- reactos/lib/riched20/reader.c | 73 +++++++++++++++++++++------------- reactos/lib/riched20/row.c | 3 +- reactos/lib/riched20/style.c | 2 +- reactos/lib/riched20/writer.c | 20 +++++----- 7 files changed, 95 insertions(+), 66 deletions(-) diff --git a/reactos/lib/riched20/editor.c b/reactos/lib/riched20/editor.c index a074d5545de..d0667201202 100644 --- a/reactos/lib/riched20/editor.c +++ b/reactos/lib/riched20/editor.c @@ -515,9 +515,9 @@ void ME_StreamInFill(ME_InStream *stream) { stream->editstream->dwError = stream->editstream->pfnCallback(stream->editstream->dwCookie, - stream->buffer, + (BYTE *)stream->buffer, sizeof(stream->buffer), - &stream->dwSize); + (LONG *)&stream->dwSize); stream->dwUsed = 0; } @@ -1097,7 +1097,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP SCROLLINFO si; ME_TextEditor *editor = (ME_TextEditor *)GetWindowLongW(hWnd, 0); - TRACE("hWnd %p msg %d (%s) %08x %08lx\n", + TRACE("hWnd %p msg %04x (%s) %08x %08lx\n", hWnd, msg, get_msg_name(msg), wParam, lParam); switch(msg) { @@ -1188,7 +1188,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP UINT from, to; PUINT pfrom = wParam ? (PUINT)wParam : &from; PUINT pto = lParam ? (PUINT)lParam : &to; - ME_GetSelection(editor, pfrom, pto); + ME_GetSelection(editor, (int *)pfrom, (int *)pto); if ((*pfrom|*pto) & 0xFFFF0000) return -1; return MAKELONG(*pfrom,*pto); @@ -1359,13 +1359,14 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP if (nPos<0) nPos = 0; if (nPos != editor->nScrollPosY) { + int dy = editor->nScrollPosY - nPos; + editor->nScrollPosY = nPos; + SetScrollPos(hWnd, SB_VERT, nPos, TRUE); if (editor->bRedraw) { - ScrollWindow(hWnd, 0, editor->nScrollPosY-nPos, NULL, NULL); - SetScrollPos(hWnd, SB_VERT, nPos, TRUE); + ScrollWindow(hWnd, 0, dy, NULL, NULL); UpdateWindow(hWnd); } - editor->nScrollPosY = nPos; } return TRUE; /* Should return false if a single line richedit control */ } @@ -1622,7 +1623,7 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP case EM_LINELENGTH: { ME_DisplayItem *item, *item_end; - int nChars = 0; + int nChars = 0, nThisLineOfs = 0, nNextLineOfs = 0; if (wParam > ME_GetTextLength(editor)) return 0; @@ -1633,17 +1634,13 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP } item = ME_FindItemAtOffset(editor, diRun, wParam, NULL); item = ME_RowStart(item); - item_end = ME_RowEnd(item); - if (!item_end) - { - /* Empty buffer, no runs */ - nChars = 0; - } + nThisLineOfs = ME_CharOfsFromRunOfs(editor, ME_FindItemFwd(item, diRun), 0); + item_end = ME_FindItemFwd(item, diStartRow); + if (item_end) + nNextLineOfs = ME_CharOfsFromRunOfs(editor, ME_FindItemFwd(item_end, diRun), 0); else - { - nChars = ME_CharOfsFromRunOfs(editor, item_end, ME_StrLen(item_end->member.run.strText)); - nChars -= ME_CharOfsFromRunOfs(editor, item, 0); - } + nNextLineOfs = ME_FindItemFwd(item, diParagraphOrEnd)->member.para.nCharOfs-1; + nChars = nNextLineOfs - nThisLineOfs; TRACE("EM_LINELENGTH(%d)==%d\n",wParam, nChars); return nChars; } @@ -1849,13 +1846,14 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP break; } if (nPos != editor->nScrollPosY) { + int dy = editor->nScrollPosY - nPos; + editor->nScrollPosY = nPos; + SetScrollPos(hWnd, SB_VERT, nPos, TRUE); if (editor->bRedraw) { - ScrollWindow(hWnd, 0, editor->nScrollPosY-nPos, NULL, NULL); - SetScrollPos(hWnd, SB_VERT, nPos, TRUE); + ScrollWindow(hWnd, 0, dy, NULL, NULL); UpdateWindow(hWnd); } - editor->nScrollPosY = nPos; } break; } @@ -1872,13 +1870,14 @@ LRESULT WINAPI RichEditANSIWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lP if (nPos<0) nPos = 0; if (nPos != editor->nScrollPosY) { + int dy = editor->nScrollPosY - nPos; + editor->nScrollPosY = nPos; + SetScrollPos(hWnd, SB_VERT, nPos, TRUE); if (editor->bRedraw) { - ScrollWindow(hWnd, 0, editor->nScrollPosY-nPos, NULL, NULL); - SetScrollPos(hWnd, SB_VERT, nPos, TRUE); + ScrollWindow(hWnd, 0, dy, NULL, NULL); UpdateWindow(hWnd); } - editor->nScrollPosY = nPos; } break; } diff --git a/reactos/lib/riched20/editor.h b/reactos/lib/riched20/editor.h index b168d01481d..7229aaff5eb 100644 --- a/reactos/lib/riched20/editor.h +++ b/reactos/lib/riched20/editor.h @@ -98,7 +98,7 @@ int ME_ReverseFindWhitespaceV(ME_String *s, int nVChar); /* row.c */ ME_DisplayItem *ME_FindRowStart(ME_Context *c, ME_DisplayItem *run, int nRelPos); ME_DisplayItem *ME_RowStart(ME_DisplayItem *item); -ME_DisplayItem *ME_RowEnd(ME_DisplayItem *item); +/* ME_DisplayItem *ME_RowEnd(ME_DisplayItem *item); */ void ME_RenumberParagraphs(ME_DisplayItem *item); /* TODO */ ME_DisplayItem *ME_FindRowWithNumber(ME_TextEditor *editor, int nRow); int ME_RowNumberFromCharOfs(ME_TextEditor *editor, int nOfs); diff --git a/reactos/lib/riched20/editstr.h b/reactos/lib/riched20/editstr.h index 39de7e1282b..2e8f1756467 100644 --- a/reactos/lib/riched20/editstr.h +++ b/reactos/lib/riched20/editstr.h @@ -161,6 +161,18 @@ typedef struct tagME_Row int nYPos; } ME_Row; +/* the display item list layout is like this: + * - the document consists of paragraphs + * - each paragraph contains at least one run, the last run in the paragraph + * is an end-of-paragraph run + * - each formatted paragraph contains at least one row, which corresponds + * to a screen line (that's why there are no rows in an unformatted + * paragraph + * - the paragraphs contain "shortcut" pointers to the previous and the next + * paragraph, that makes iteration over paragraphs faster + * - the list starts with diTextStart and ends with diTextEnd + */ + typedef struct tagME_DisplayItem { ME_DIType type; @@ -212,7 +224,7 @@ struct tagME_InStream { EDITSTREAM *editstream; DWORD dwSize; DWORD dwUsed; - BYTE buffer[STREAMIN_BUFFER_SIZE]; + char buffer[STREAMIN_BUFFER_SIZE]; }; typedef struct tagME_InStream ME_InStream; diff --git a/reactos/lib/riched20/reader.c b/reactos/lib/riched20/reader.c index 25805c21111..5c104e1c90c 100644 --- a/reactos/lib/riched20/reader.c +++ b/reactos/lib/riched20/reader.c @@ -127,10 +127,13 @@ int _RTFGetChar(RTF_Info *info) TRACE("\n"); - /* if the last buffer wasn't full, it's EOF */ + /* Doc says, that if the last buffer wasn't full, it's EOF. + Actually, that's not true. */ +/* if (stream->dwSize > 0 && stream->dwSize == stream->dwUsed && stream->dwSize < sizeof(stream->buffer)) return EOF; +*/ if (stream->dwSize <= stream->dwUsed) { ME_StreamInFill(stream); @@ -1089,12 +1092,15 @@ static void ReadStyleSheet(RTF_Info *info) RTFStyleElt *sep, *sepLast; char buf[rtfBufSiz], *bp; const char *fn = "ReadStyleSheet"; + int real_style; TRACE("\n"); for (;;) { RTFGetToken (info); + if (info->rtfClass == rtfEOF) + break; if (RTFCheckCM (info, rtfGroup, rtfEndGroup)) break; sp = New (RTFStyle); @@ -1112,6 +1118,7 @@ static void ReadStyleSheet(RTF_Info *info) info->styleList = sp; if (!RTFCheckCM (info, rtfGroup, rtfBeginGroup)) RTFPanic (info,"%s: missing \"{\"", fn); + real_style = TRUE; for (;;) { RTFGetToken (info); @@ -1120,8 +1127,15 @@ static void ReadStyleSheet(RTF_Info *info) break; if (info->rtfClass == rtfControl) { - if (RTFCheckMM (info, rtfSpecialChar, rtfOptDest)) - continue; /* ignore "\*" */ + if (RTFCheckMM (info, rtfSpecialChar, rtfOptDest)) { + RTFGetToken(info); + RTFPanic(info, "%s: skipping optional destination", fn); + RTFSkipGroup(info); + info->rtfClass = rtfGroup; + info->rtfMajor = rtfEndGroup; + real_style = FALSE; + break; /* ignore "\*" */ + } if (RTFCheckMM (info, rtfParAttr, rtfStyleNum)) { sp->rtfSNum = info->rtfParam; @@ -1178,6 +1192,7 @@ static void ReadStyleSheet(RTF_Info *info) * This passes over "{\*\keycode ... }, among * other things. A temporary (perhaps) hack. */ + RTFPanic(info, "%s: skipping begin", fn); RTFSkipGroup (info); continue; } @@ -1207,31 +1222,33 @@ static void ReadStyleSheet(RTF_Info *info) fn, info->rtfTextBuf); } } - RTFGetToken (info); - if (!RTFCheckCM (info, rtfGroup, rtfEndGroup)) - RTFPanic (info, "%s: missing \"}\"", fn); - - /* - * Check over the style structure. A name is a must. - * If no style number was specified, check whether it's the - * Normal style (in which case it's given style number - * rtfNormalStyleNum). Note that some "normal" style names - * just begin with "Normal" and can have other stuff following, - * e.g., "Normal,Times 10 point". Ugh. - * - * Some German RTF writers use "Standard" instead of "Normal". - */ - if (sp->rtfSName == NULL) - RTFPanic (info,"%s: missing style name", fn); - if (sp->rtfSNum < 0) - { - if (strncmp (buf, "Normal", 6) != 0 - && strncmp (buf, "Standard", 8) != 0) - RTFPanic (info,"%s: missing style number", fn); - sp->rtfSNum = rtfNormalStyleNum; + if (real_style) { + RTFGetToken (info); + if (!RTFCheckCM (info, rtfGroup, rtfEndGroup)) + RTFPanic (info, "%s: missing \"}\"", fn); + /* + * Check over the style structure. A name is a must. + * If no style number was specified, check whether it's the + * Normal style (in which case it's given style number + * rtfNormalStyleNum). Note that some "normal" style names + * just begin with "Normal" and can have other stuff following, + * e.g., "Normal,Times 10 point". Ugh. + * + * Some German RTF writers use "Standard" instead of "Normal". + */ + if (sp->rtfSName == NULL) + RTFPanic (info,"%s: missing style name", fn); + if (sp->rtfSNum < 0) + { + if (strncmp (buf, "Normal", 6) != 0 + && strncmp (buf, "Standard", 8) != 0) + RTFPanic (info,"%s: missing style number", fn); + sp->rtfSNum = rtfNormalStyleNum; + } + if (sp->rtfSNextPar == -1) /* if \snext not given, */ + sp->rtfSNextPar = sp->rtfSNum; /* next is itself */ } - if (sp->rtfSNextPar == -1) /* if \snext not given, */ - sp->rtfSNextPar = sp->rtfSNum; /* next is itself */ + /* otherwise we're just dealing with fake end group from skipped group */ } RTFRouteToken (info); /* feed "}" back to router */ } @@ -2755,7 +2772,7 @@ RTFFlushCPOutputBuffer(RTF_Info *info) int length; length = MultiByteToWideChar(info->codePage, 0, info->cpOutputBuffer, - info->dwCPOutputCount, buffer, bufferMax); + info->dwCPOutputCount, buffer, bufferMax/sizeof(WCHAR)); info->dwCPOutputCount = 0; RTFPutUnicodeString(info, buffer, length); diff --git a/reactos/lib/riched20/row.c b/reactos/lib/riched20/row.c index d7a6bd158e2..f3e3cc1b5f3 100644 --- a/reactos/lib/riched20/row.c +++ b/reactos/lib/riched20/row.c @@ -77,12 +77,13 @@ ME_DisplayItem *ME_RowStart(ME_DisplayItem *item) { return ME_FindItemBackOrHere(item, diStartRow); } +/* ME_DisplayItem *ME_RowEnd(ME_DisplayItem *item) { ME_DisplayItem *item2 = ME_FindItemFwd(item, diStartRowOrParagraphOrEnd); if (!item2) return NULL; return ME_FindItemBack(item, diRun); } - +*/ ME_DisplayItem * ME_FindRowWithNumber(ME_TextEditor *editor, int nRow) diff --git a/reactos/lib/riched20/style.c b/reactos/lib/riched20/style.c index 3cc543a3b9e..1d06154adfc 100644 --- a/reactos/lib/riched20/style.c +++ b/reactos/lib/riched20/style.c @@ -52,7 +52,7 @@ CHARFORMAT2W *ME_ToCF2W(CHARFORMAT2W *to, CHARFORMAT2W *from) CopyMemory(to, f, sizeof(CHARFORMATA)-sizeof(f->szFaceName)); /* convert face name */ if (f->dwMask & CFM_FACE) - MultiByteToWideChar(0, 0, f->szFaceName, -1, to->szFaceName, sizeof(to->szFaceName)); + MultiByteToWideChar(0, 0, f->szFaceName, -1, to->szFaceName, sizeof(to->szFaceName)/sizeof(WCHAR)); /* copy the rest of the 2A structure to 2W */ CopyMemory(1+((CHARFORMATW *)to), f+1, sizeof(CHARFORMAT2A)-sizeof(CHARFORMATA)); to->cbSize = sizeof(CHARFORMAT2W); diff --git a/reactos/lib/riched20/writer.c b/reactos/lib/riched20/writer.c index 11d55a8917f..629cce2e439 100644 --- a/reactos/lib/riched20/writer.c +++ b/reactos/lib/riched20/writer.c @@ -55,7 +55,7 @@ ME_StreamOutFlush(ME_TextEditor *editor) on initial random nWritten value, which is usually >STREAMOUT_BUFFER_SIZE */ nRemaining = editor->pStream->pos - nStart; nWritten = 0xDEADBEEF; - stream->dwError = stream->pfnCallback(stream->dwCookie, editor->pStream->buffer + nStart, + stream->dwError = stream->pfnCallback(stream->dwCookie, (LPBYTE)editor->pStream->buffer + nStart, editor->pStream->pos - nStart, &nWritten); TRACE("error=%lu written=%lu\n", stream->dwError, nWritten); if (nWritten > (editor->pStream->pos - nStart) || nWritten<0) { @@ -86,7 +86,7 @@ ME_StreamOutFree(ME_TextEditor *editor) static BOOL -ME_StreamOutMove(ME_TextEditor *editor, BYTE *buffer, int len) +ME_StreamOutMove(ME_TextEditor *editor, const char *buffer, int len) { ME_OutStream *pStream = editor->pStream; @@ -599,8 +599,8 @@ ME_StreamOutRTFText(ME_TextEditor *editor, WCHAR *text, LONG nChars) nChars--; } else { BOOL unknown = FALSE; - BYTE letter[3]; - + char letter[3]; + /* FIXME: In the MS docs for WideCharToMultiByte there is a big list of * codepages including CP_SYMBOL for which the last parameter must be set * to NULL for the function to succeed. But in Wine we need to care only @@ -610,7 +610,7 @@ ME_StreamOutRTFText(ME_TextEditor *editor, WCHAR *text, LONG nChars) (editor->pStream->nCodePage == CP_SYMBOL) ? NULL : &unknown); if (unknown) pos += sprintf(buffer + pos, "\\u%d?", (short)*text); - else if (*letter < 128) { + else if ((BYTE)*letter < 128) { if (*letter == '{' || *letter == '}' || *letter == '\\') buffer[pos++] = '\\'; buffer[pos++] = *letter; @@ -720,7 +720,7 @@ ME_StreamOutText(ME_TextEditor *editor, int nStart, int nChars, DWORD dwFormat) ME_DisplayItem *item = ME_FindItemAtOffset(editor, diRun, nStart, &nStart); int nLen; UINT nCodePage = CP_ACP; - BYTE *buffer = NULL; + char *buffer = NULL; int nBufLen = 0; BOOL success = TRUE; @@ -738,15 +738,15 @@ ME_StreamOutText(ME_TextEditor *editor, int nStart, int nChars, DWORD dwFormat) nLen = nChars; if (item->member.run.nFlags & MERF_ENDPARA) { - WCHAR szEOL[] = { '\r', '\n' }; + static const WCHAR szEOL[2] = { '\r', '\n' }; if (dwFormat & SF_UNICODE) - success = ME_StreamOutMove(editor, (BYTE *)szEOL, 4); + success = ME_StreamOutMove(editor, (const char *)szEOL, sizeof(szEOL)); else success = ME_StreamOutMove(editor, "\r\n", 2); } else { if (dwFormat & SF_UNICODE) - success = ME_StreamOutMove(editor, (BYTE *)(item->member.run.strText->szData + nStart), + success = ME_StreamOutMove(editor, (const char *)(item->member.run.strText->szData + nStart), sizeof(WCHAR) * nLen); else { int nSize; @@ -756,7 +756,7 @@ ME_StreamOutText(ME_TextEditor *editor, int nStart, int nChars, DWORD dwFormat) if (nSize > nBufLen) { if (buffer) FREE_OBJ(buffer); - buffer = ALLOC_N_OBJ(BYTE, nSize); + buffer = ALLOC_N_OBJ(char, nSize); nBufLen = nSize; } WideCharToMultiByte(nCodePage, 0, item->member.run.strText->szData + nStart,