Sync to Wine-20050930: Rein Klazes wijn@wanadoo.nl - When scrolling, first update the new position of the control before calling UpdateWindow(). Alexandre Julliard julliard@winehq.org - Fixed gcc 4.0 warnings. - We are no longer generating .dbg.c files. Krzysztof Foltman wdev@foltman.com - 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 marcus@jet.franken.de - The last argument to MultiByteToWideChar is wide character count and not the buffer size in bytes. Fixed all places where it was wrong. Modified: trunk/reactos/lib/riched20/editor.c Modified: trunk/reactos/lib/riched20/editor.h Modified: trunk/reactos/lib/riched20/editstr.h Modified: trunk/reactos/lib/riched20/reader.c Modified: trunk/reactos/lib/riched20/row.c Modified: trunk/reactos/lib/riched20/style.c Modified: trunk/reactos/lib/riched20/writer.c _____
Modified: trunk/reactos/lib/riched20/editor.c --- trunk/reactos/lib/riched20/editor.c 2005-10-08 17:15:42 UTC (rev 18344) +++ trunk/reactos/lib/riched20/editor.c 2005-10-08 17:17:27 UTC (rev 18345) @@ -515,9 +515,9 @@
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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } 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 @@ 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 @@ 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; } _____
Modified: trunk/reactos/lib/riched20/editor.h --- trunk/reactos/lib/riched20/editor.h 2005-10-08 17:15:42 UTC (rev 18344) +++ trunk/reactos/lib/riched20/editor.h 2005-10-08 17:17:27 UTC (rev 18345) @@ -98,7 +98,7 @@
/* 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); _____
Modified: trunk/reactos/lib/riched20/editstr.h --- trunk/reactos/lib/riched20/editstr.h 2005-10-08 17:15:42 UTC (rev 18344) +++ trunk/reactos/lib/riched20/editstr.h 2005-10-08 17:17:27 UTC (rev 18345) @@ -161,6 +161,18 @@
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 @@ EDITSTREAM *editstream; DWORD dwSize; DWORD dwUsed; - BYTE buffer[STREAMIN_BUFFER_SIZE]; + char buffer[STREAMIN_BUFFER_SIZE]; }; typedef struct tagME_InStream ME_InStream;
_____
Modified: trunk/reactos/lib/riched20/reader.c --- trunk/reactos/lib/riched20/reader.c 2005-10-08 17:15:42 UTC (rev 18344) +++ trunk/reactos/lib/riched20/reader.c 2005-10-08 17:17:27 UTC (rev 18345) @@ -127,10 +127,13 @@
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 @@ 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 @@ info->styleList = sp; if (!RTFCheckCM (info, rtfGroup, rtfBeginGroup)) RTFPanic (info,"%s: missing "{"", fn); + real_style = TRUE; for (;;) { RTFGetToken (info); @@ -1120,8 +1127,15 @@ 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 @@ * This passes over "{*\keycode ... }, among * other things. A temporary (perhaps) hack. */ + RTFPanic(info, "%s: skipping begin", fn); RTFSkipGroup (info); continue; } @@ -1207,31 +1222,33 @@ 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 @@ 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); _____
Modified: trunk/reactos/lib/riched20/row.c --- trunk/reactos/lib/riched20/row.c 2005-10-08 17:15:42 UTC (rev 18344) +++ trunk/reactos/lib/riched20/row.c 2005-10-08 17:17:27 UTC (rev 18345) @@ -77,13 +77,14 @@
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) { _____
Modified: trunk/reactos/lib/riched20/style.c --- trunk/reactos/lib/riched20/style.c 2005-10-08 17:15:42 UTC (rev 18344) +++ trunk/reactos/lib/riched20/style.c 2005-10-08 17:17:27 UTC (rev 18345) @@ -52,7 +52,7 @@
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); _____
Modified: trunk/reactos/lib/riched20/writer.c --- trunk/reactos/lib/riched20/writer.c 2005-10-08 17:15:42 UTC (rev 18344) +++ trunk/reactos/lib/riched20/writer.c 2005-10-08 17:17:27 UTC (rev 18345) @@ -55,7 +55,7 @@
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 @@
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 @@ 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 @@ (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_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 @@ 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 @@ 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,