Sync to Wine-0_9:
Phil Krylov <phil(a)newstar.rinet.ru>
- Fixed encoding of non-ASCII chars.
Krzysztof Foltman <wdev(a)foltman.com>
- Bugfix in EM_GETTEXTEX
- Additional traces helpful in diagnosing similar (text
retrieval-related) bugs.
- Fix unnecessary (and harmful) repeated statement.
- Removed buffer overrun error (incrementing output pointer one time too
much in non-CRLF mode) making KeyNote fail to install.
- Style trace information is written to different debug channel (it's
not very useful anymore, reference counting looks correct for now).
- The document dump contains the character position of the end-of-text
mark.
- The previous implementation was a workaround for off-by-one bug in
ME_RunOfsFromCharOfs, this one relies on correct behavior of that
function introduced by the previous patch.
- Send verbose info to different debug channels (richedit_check for
output from offset checker, richedit_lists for the document list
dumps).
- Fix a bug in 1.0 emulation mode in EM_LINELENGTH (which broke PTE
installer).
- Fixed EOL detection in ME_RunOfsFromCharOfs in 1.0 emulation mode
(necessary for a non-workaround version of EM_POSFROMCHAR).
- Fix 1.0 emulation mode in ME_GetTextW.
- Remove another potential sources of infinite loops caused by EOF in
the middle of the font and color tables.
- Closing brace on text level is treated as EOF (effectively
protecting the control from trash after the end of RTF).
- Removed misleading comment about incomplete buffers (I was
definitely wrong).
- Implemented EM_GETFIRSTVISIBLELINE and EM_POSFROMCHAR (basic
suboptimal implementation, can be optimized to skip whole paragraphs
later if it's useful at all).
- Fixed another case of misunderstanding MSDN wrt StreamInProc, causing
license text to be truncated in Picasa installer (as well as some
other programs, especially those that display long texts with NSIS).
Modified: trunk/reactos/lib/riched20/editor.c
Modified: trunk/reactos/lib/riched20/list.c
Modified: trunk/reactos/lib/riched20/reader.c
Modified: trunk/reactos/lib/riched20/run.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-11-02 19:28:16 UTC (rev
18954)
+++ trunk/reactos/lib/riched20/editor.c 2005-11-02 20:03:07 UTC (rev
18955)
@@ -43,7 +43,7 @@
- EM_GETCHARFORMAT (partly done)
- EM_GETEDITSTYLE
+ EM_GETEVENTMASK
- - EM_GETFIRSTVISIBLELINE
+ + EM_GETFIRSTVISIBLELINE (can be optimized if needed)
- EM_GETIMECOLOR 1.0asian
- EM_GETIMECOMPMODE 2.0
- EM_GETIMEOPTIONS 1.0asian
@@ -81,7 +81,7 @@
+ EM_LINELENGTH
+ EM_LINESCROLL
- EM_PASTESPECIAL
- - EM_POSFROMCHARS
+ + EM_POSFROMCHAR
+ EM_REDO 2.0
- EM_REQUESTRESIZE
+ EM_REPLACESEL (proper style?) ANSI&Unicode
@@ -290,7 +290,7 @@
}
ME_InsertTextFromCursor(editor, 0, pText, nWideChars, style);
- if (stream->dwSize < STREAMIN_BUFFER_SIZE)
+ if (stream->dwSize == 0)
break;
stream->dwSize = 0;
} while(1);
@@ -483,7 +483,12 @@
{
ME_Style *s;
RTFFlushOutputBuffer(info);
+ if (info->stackTop<=1) {
+ info->rtfClass = rtfEOF;
+ return;
+ }
info->stackTop--;
+ assert(info->stackTop >= 0);
if (info->styleChanged)
{
/* FIXME too slow ? how come ? */
@@ -1111,7 +1116,6 @@
UNSUPPORTED_MSG(EM_GETAUTOURLDETECT)
UNSUPPORTED_MSG(EM_GETBIDIOPTIONS)
UNSUPPORTED_MSG(EM_GETEDITSTYLE)
- UNSUPPORTED_MSG(EM_GETFIRSTVISIBLELINE)
UNSUPPORTED_MSG(EM_GETIMECOMPMODE)
/* UNSUPPORTED_MSG(EM_GETIMESTATUS) missing in Wine headers */
UNSUPPORTED_MSG(EM_GETLANGOPTIONS)
@@ -1130,7 +1134,6 @@
UNSUPPORTED_MSG(EM_HIDESELECTION)
UNSUPPORTED_MSG(EM_LIMITTEXT) /* also known as EM_SETLIMITTEXT */
UNSUPPORTED_MSG(EM_PASTESPECIAL)
-/* UNSUPPORTED_MSG(EM_POSFROMCHARS) missing in Wine headers */
UNSUPPORTED_MSG(EM_REQUESTRESIZE)
UNSUPPORTED_MSG(EM_SCROLL)
UNSUPPORTED_MSG(EM_SCROLLCARET)
@@ -1350,6 +1353,30 @@
case EM_GETPARAFORMAT:
ME_GetSelectionParaFormat(editor, (PARAFORMAT2 *)lParam);
return 0;
+ case EM_GETFIRSTVISIBLELINE:
+ {
+ ME_DisplayItem *p = editor->pBuffer->pFirst;
+ int y = editor->nScrollPosY;
+ int ypara = 0;
+ int count = 0;
+ int ystart, yend;
+ while(p) {
+ p = ME_FindItemFwd(p, diStartRowOrParagraphOrEnd);
+ if (p->type == diTextEnd)
+ break;
+ if (p->type == diParagraph) {
+ ypara = p->member.para.nYPos;
+ continue;
+ }
+ ystart = ypara + p->member.row.nYPos;
+ yend = ystart + p->member.row.nHeight;
+ if (y < yend) {
+ break;
+ }
+ count++;
+ }
+ return count;
+ }
case EM_LINESCROLL:
{
int nPos = editor->nScrollPosY, nEnd= editor->nTotalLength -
editor->sizeWindow.cy;
@@ -1538,16 +1565,19 @@
}
else
{
- LPWSTR buffer = HeapAlloc(GetProcessHeap(), 0, (nCount + 1) *
sizeof(WCHAR));
- DWORD buflen = ex->cb;
- LRESULT rc;
- DWORD flags = 0;
+ /* potentially each char may be a CR, why calculate the exact
value with O(N) when
+ we can just take a bigger buffer? :) */
+ int crlfmul = (ex->flags & GT_USECRLF) ? 2 : 1;
+ LPWSTR buffer = HeapAlloc(GetProcessHeap(), 0, (crlfmul*nCount +
1) * sizeof(WCHAR));
+ DWORD buflen = ex->cb;
+ LRESULT rc;
+ DWORD flags = 0;
- buflen = ME_GetTextW(editor, buffer, nStart, nCount, ex->flags
& GT_USECRLF);
- rc = WideCharToMultiByte(ex->codepage, flags, buffer, buflen,
(LPSTR)lParam, ex->cb, ex->lpDefaultChar, ex->lpUsedDefaultChar);
+ buflen = ME_GetTextW(editor, buffer, nStart, nCount, ex->flags &
GT_USECRLF);
+ rc = WideCharToMultiByte(ex->codepage, flags, buffer, buflen,
(LPSTR)lParam, ex->cb, ex->lpDefaultChar, ex->lpUsedDefaultChar);
- HeapFree(GetProcessHeap(),0,buffer);
- return rc;
+ HeapFree(GetProcessHeap(),0,buffer);
+ return rc;
}
}
case EM_GETSELTEXT:
@@ -1563,6 +1593,9 @@
case EM_GETTEXTRANGE:
{
TEXTRANGEW *rng = (TEXTRANGEW *)lParam;
+ TRACE("EM_GETTEXTRANGE min=%ld max=%ld unicode=%d emul1.0=%d
length=%d\n",
+ rng->chrg.cpMin, rng->chrg.cpMax, IsWindowUnicode(hWnd),
+ editor->bEmulateVersion10, ME_GetTextLength(editor));
if (IsWindowUnicode(hWnd))
return ME_GetTextW(editor, rng->lpstrText, rng->chrg.cpMin,
rng->chrg.cpMax-rng->chrg.cpMin, editor->bEmulateVersion10);
else
@@ -1639,7 +1672,8 @@
if (item_end)
nNextLineOfs = ME_CharOfsFromRunOfs(editor,
ME_FindItemFwd(item_end, diRun), 0);
else
- nNextLineOfs = ME_FindItemFwd(item,
diParagraphOrEnd)->member.para.nCharOfs-1;
+ nNextLineOfs = ME_FindItemFwd(item,
diParagraphOrEnd)->member.para.nCharOfs
+ - (editor->bEmulateVersion10?2:1);
nChars = nNextLineOfs - nThisLineOfs;
TRACE("EM_LINELENGTH(%d)==%d\n",wParam, nChars);
return nChars;
@@ -1684,6 +1718,33 @@
return ME_SetZoom(editor, wParam, lParam);
case EM_CHARFROMPOS:
return ME_CharFromPos(editor, ((POINTL *)lParam)->x, ((POINTL
*)lParam)->y);
+ case EM_POSFROMCHAR:
+ {
+ ME_DisplayItem *pRun;
+ int nCharOfs, nOffset, nLength;
+ POINTL pt = {0,0};
+
+ nCharOfs = wParam;
+ /* detect which API version we're dealing with */
+ if (wParam >= 0x40000)
+ nCharOfs = lParam;
+ nLength = ME_GetTextLength(editor);
+
+ if (nCharOfs < nLength) {
+ ME_RunOfsFromCharOfs(editor, nCharOfs, &pRun, &nOffset);
+ assert(pRun->type == diRun);
+ pt.y = pRun->member.run.pt.y;
+ pt.x = pRun->member.run.pt.x + ME_PointFromChar(editor,
&pRun->member.run, nOffset);
+ pt.y += ME_GetParagraph(pRun)->member.para.nYPos;
+ } else {
+ pt.x = 0;
+ pt.y = editor->pBuffer->pLast->member.para.nYPos;
+ }
+ if (wParam >= 0x40000) {
+ *(POINTL *)wParam = pt;
+ }
+ return MAKELONG( pt.x, pt.y );
+ }
case WM_CREATE:
ME_CommitUndo(editor);
ME_WrapMarkedParagraphs(editor);
@@ -1982,12 +2043,12 @@
{
ME_DisplayItem *item = ME_FindItemAtOffset(editor, diRun, nStart,
&nStart);
int nWritten = 0;
+ WCHAR *pStart = buffer;
if (!item) {
*buffer = L'\0';
return 0;
}
- assert(item);
if (nStart)
{
@@ -2012,13 +2073,16 @@
if (item->member.run.nFlags & MERF_ENDPARA)
{
- *buffer++ = '\r';
+ *buffer = '\r';
if (bCRLF)
{
- *buffer = '\n';
+ *(++buffer) = '\n';
nWritten++;
}
assert(nLen == 1);
+ /* our end paragraph consists of 2 characters now */
+ if (editor->bEmulateVersion10)
+ nChars--;
}
else
CopyMemory(buffer, item->member.run.strText->szData,
sizeof(WCHAR)*nLen);
@@ -2028,12 +2092,14 @@
if (!nChars)
{
+ TRACE("nWritten=%d, actual=%d\n", nWritten, buffer-pStart);
*buffer = L'\0';
return nWritten;
}
item = ME_FindItemFwd(item, diRun);
}
*buffer = L'\0';
+ TRACE("nWritten=%d, actual=%d\n", nWritten, buffer-pStart);
return nWritten;
}
_____
Modified: trunk/reactos/lib/riched20/list.c
--- trunk/reactos/lib/riched20/list.c 2005-11-02 19:28:16 UTC (rev
18954)
+++ trunk/reactos/lib/riched20/list.c 2005-11-02 20:03:07 UTC (rev
18955)
@@ -21,7 +21,7 @@
#include "editor.h"
-WINE_DEFAULT_DEBUG_CHANNEL(riched20);
+WINE_DEFAULT_DEBUG_CHANNEL(richedit_lists);
void ME_InsertBefore(ME_DisplayItem *diWhere, ME_DisplayItem *diWhat)
{
@@ -181,7 +181,7 @@
pItem->member.run.nCharOfs);
break;
case diTextEnd:
- TRACE("\nEnd\n");
+ TRACE("\nEnd(ofs=%d)\n", pItem->member.para.nCharOfs);
break;
default:
break;
_____
Modified: trunk/reactos/lib/riched20/reader.c
--- trunk/reactos/lib/riched20/reader.c 2005-11-02 19:28:16 UTC (rev
18954)
+++ trunk/reactos/lib/riched20/reader.c 2005-11-02 20:03:07 UTC (rev
18955)
@@ -127,13 +127,6 @@
TRACE("\n");
- /* 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);
@@ -455,6 +448,10 @@
RTFFuncPtr p;
TRACE("\n");
+ /* don't try to return anything once EOF is reached */
+ if (info->rtfClass == rtfEOF) {
+ return rtfEOF;
+ }
for (;;)
{
@@ -885,6 +882,8 @@
for (;;)
{
RTFGetToken (info);
+ if (info->rtfClass == rtfEOF)
+ break;
if (RTFCheckCM (info, rtfGroup, rtfEndGroup))
break;
if (old < 0) /* first entry - determine tbl
type */
@@ -901,6 +900,8 @@
if (!RTFCheckCM (info, rtfGroup, rtfBeginGroup))
RTFPanic (info, "%s: missing \"{\"",
fn);
RTFGetToken (info); /* yes, skip to next
token */
+ if (info->rtfClass == rtfEOF)
+ break;
}
fp = New (RTFFont);
if (fp == NULL)
@@ -1002,12 +1003,18 @@
fn,info->rtfTextBuf);
}
RTFGetToken (info);
+ if (info->rtfClass == rtfEOF)
+ break;
}
+ if (info->rtfClass == rtfEOF)
+ break;
if (old == 0) /* need to see "}" here */
{
RTFGetToken (info);
if (!RTFCheckCM (info, rtfGroup, rtfEndGroup))
RTFPanic (info, "%s: missing \"}\"",
fn);
+ if (info->rtfClass == rtfEOF)
+ break;
}
/* Apply the real properties of the default font */
@@ -1055,6 +1062,8 @@
for (;;)
{
RTFGetToken (info);
+ if (info->rtfClass == rtfEOF)
+ break;
if (RTFCheckCM (info, rtfGroup, rtfEndGroup))
break;
cp = New (RTFColor);
@@ -1074,6 +1083,8 @@
}
RTFGetToken (info);
}
+ if (info->rtfClass == rtfEOF)
+ break;
if (!RTFCheckCM (info, rtfText, ';'))
RTFPanic (info,"%s: malformed entry", fn);
}
_____
Modified: trunk/reactos/lib/riched20/run.c
--- trunk/reactos/lib/riched20/run.c 2005-11-02 19:28:16 UTC (rev
18954)
+++ trunk/reactos/lib/riched20/run.c 2005-11-02 20:03:07 UTC (rev
18955)
@@ -23,6 +23,8 @@
#include "editor.h"
WINE_DEFAULT_DEBUG_CHANNEL(richedit);
+WINE_DECLARE_DEBUG_CHANNEL(richedit_check);
+WINE_DECLARE_DEBUG_CHANNEL(richedit_lists);
int ME_CanJoinRuns(ME_Run *run1, ME_Run *run2)
{
@@ -72,26 +74,26 @@
{
ME_DisplayItem *p = editor->pBuffer->pFirst;
int ofs = 0, ofsp = 0;
- if(TRACE_ON(richedit))
+ if(TRACE_ON(richedit_lists))
{
- TRACE("---\n");
+ TRACE_(richedit_lists)("---\n");
ME_DumpDocument(editor->pBuffer);
}
do {
p = ME_FindItemFwd(p, diRunOrParagraphOrEnd);
switch(p->type) {
case diTextEnd:
- TRACE("tend, real ofsp = %d, counted = %d\n",
p->member.para.nCharOfs, ofsp+ofs);
+ TRACE_(richedit_check)("tend, real ofsp = %d, counted = %d\n",
p->member.para.nCharOfs, ofsp+ofs);
assert(ofsp+ofs == p->member.para.nCharOfs);
return;
case diParagraph:
- TRACE("para, real ofsp = %d, counted = %d\n",
p->member.para.nCharOfs, ofsp+ofs);
+ TRACE_(richedit_check)("para, real ofsp = %d, counted = %d\n",
p->member.para.nCharOfs, ofsp+ofs);
assert(ofsp+ofs == p->member.para.nCharOfs);
ofsp = p->member.para.nCharOfs;
ofs = 0;
break;
case diRun:
- TRACE("run, real ofs = %d (+ofsp = %d), counted = %d, len = %d,
txt = \"%s\", flags=%08x, fx&mask = %08lx\n",
+ TRACE_(richedit_check)("run, real ofs = %d (+ofsp = %d),
counted = %d, len = %d, txt = \"%s\", flags=%08x, fx&mask = %08lx\n",
p->member.run.nCharOfs, p->member.run.nCharOfs+ofsp,
ofsp+ofs,
p->member.run.strText->nLen,
debugstr_w(p->member.run.strText->szData),
p->member.run.nFlags,
@@ -143,6 +145,7 @@
if (nCharOfs < pPara->member.para.next_para->member.para.nCharOfs)
{
+ int eollen = 1;
*ppRun = ME_FindItemFwd(pPara, diRun);
assert(*ppRun);
while (!((*ppRun)->member.run.nFlags & MERF_ENDPARA))
@@ -157,7 +160,10 @@
}
*ppRun = pNext;
}
- if (nCharOfs == nParaOfs + (*ppRun)->member.run.nCharOfs) {
+ /* the handling of bEmulateVersion10 may be a source of many
bugs, I'm afraid */
+ eollen = (editor->bEmulateVersion10 ? 2 : 1);
+ if (nCharOfs >= nParaOfs + (*ppRun)->member.run.nCharOfs &&
+ nCharOfs < nParaOfs + (*ppRun)->member.run.nCharOfs + eollen) {
*pOfs = 0;
return;
}
_____
Modified: trunk/reactos/lib/riched20/style.c
--- trunk/reactos/lib/riched20/style.c 2005-11-02 19:28:16 UTC (rev
18954)
+++ trunk/reactos/lib/riched20/style.c 2005-11-02 20:03:07 UTC (rev
18955)
@@ -21,6 +21,7 @@
#include "editor.h"
WINE_DEFAULT_DEBUG_CHANNEL(richedit);
+WINE_DECLARE_DEBUG_CHANNEL(richedit_style);
static int all_refs = 0;
@@ -197,7 +198,7 @@
{
char buf[2048];
ME_DumpStyleToBuf(&s->fmt, buf);
- TRACE("%s\n", buf);
+ TRACE_(richedit_style)("%s\n", buf);
}
void ME_DumpStyleToBuf(CHARFORMAT2W *pFmt, char buf[2048])
@@ -321,7 +322,7 @@
if (i < HFONT_CACHE_SIZE) /* found */
{
item = &editor->pFontCache[i];
- TRACE("font reused %d\n", i);
+ TRACE_(richedit_style)("font reused %d\n", i);
s->hFont = item->hFont;
item->nRefs++;
@@ -332,13 +333,13 @@
assert(nEmpty != -1); /* otherwise we leak cache entries or get too
many fonts at once*/
if (item->hFont) {
- TRACE("font deleted %d\n", nEmpty);
+ TRACE_(richedit_style)("font deleted %d\n", nEmpty);
DeleteObject(item->hFont);
item->hFont = NULL;
}
s->hFont = CreateFontIndirectW(&lf);
assert(s->hFont);
- TRACE("font created %d\n", nEmpty);
+ TRACE_(richedit_style)("font created %d\n", nEmpty);
item->hFont = s->hFont;
item->nRefs = 1;
memcpy(&item->lfSpecs, &lf, sizeof(LOGFONTW));
@@ -391,9 +392,9 @@
s->nRefs--;
all_refs--;
if (s->nRefs==0)
- TRACE("destroy style %p, total refs=%d\n", s, all_refs);
+ TRACE_(richedit_style)("destroy style %p, total refs=%d\n", s,
all_refs);
else
- TRACE("release style %p, new refs=%d, total refs=%d\n", s,
s->nRefs, all_refs);
+ TRACE_(richedit_style)("release style %p, new refs=%d, total
refs=%d\n", s, s->nRefs, all_refs);
if (!all_refs) TRACE("all style references freed (good!)\n");
assert(s->nRefs>=0);
if (!s->nRefs)
_____
Modified: trunk/reactos/lib/riched20/writer.c
--- trunk/reactos/lib/riched20/writer.c 2005-11-02 19:28:16 UTC (rev
18954)
+++ trunk/reactos/lib/riched20/writer.c 2005-11-02 20:03:07 UTC (rev
18955)
@@ -616,7 +616,7 @@
buffer[pos++] = *letter;
} else {
for (i = 0; i < nBytes; i++)
- pos += sprintf(buffer + pos, "\\'%02x", letter[i]);
+ pos += sprintf(buffer + pos, "\\'%02x", (BYTE)letter[i]);
}
text++;
nChars--;