Make RTF reader fall back to simple text if a correct RTF header is
not detected. This should fix some installers.
This commit is contained in:
parent
ad7f4daf35
commit
1e9c200f61
|
@ -233,36 +233,40 @@ ME_TextBuffer *ME_MakeText() {
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define STREAMIN_BUFFER_SIZE 4096 /* M$ compatibility */
|
|
||||||
|
|
||||||
static LRESULT ME_StreamInText(ME_TextEditor *editor, DWORD dwFormat, EDITSTREAM *stream, ME_Style *style)
|
static LRESULT ME_StreamInText(ME_TextEditor *editor, DWORD dwFormat, ME_InStream *stream, ME_Style *style)
|
||||||
{
|
{
|
||||||
BYTE buffer[STREAMIN_BUFFER_SIZE+1];
|
|
||||||
WCHAR wszText[STREAMIN_BUFFER_SIZE+1];
|
WCHAR wszText[STREAMIN_BUFFER_SIZE+1];
|
||||||
|
WCHAR *pText;
|
||||||
|
|
||||||
TRACE("%08lx %p\n", dwFormat, stream);
|
TRACE("%08lx %p\n", dwFormat, stream);
|
||||||
stream->dwError = 0;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
long nDataSize = 0, nWideChars = 0;
|
long nWideChars = 0;
|
||||||
stream->dwError = stream->pfnCallback(stream->dwCookie,
|
|
||||||
(dwFormat & SF_UNICODE ? (BYTE *)wszText : buffer),
|
|
||||||
STREAMIN_BUFFER_SIZE, &nDataSize);
|
|
||||||
|
|
||||||
if (stream->dwError)
|
if (!stream->dwSize)
|
||||||
break;
|
{
|
||||||
if (!nDataSize)
|
ME_StreamInFill(stream);
|
||||||
break;
|
if (stream->editstream->dwError)
|
||||||
|
break;
|
||||||
|
if (!stream->dwSize)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(dwFormat & SF_UNICODE))
|
if (!(dwFormat & SF_UNICODE))
|
||||||
{
|
{
|
||||||
/* FIXME? this is doomed to fail on true MBCS like UTF-8, luckily they're unlikely to be used as CP_ACP */
|
/* FIXME? this is doomed to fail on true MBCS like UTF-8, luckily they're unlikely to be used as CP_ACP */
|
||||||
nWideChars = MultiByteToWideChar(CP_ACP, 0, buffer, nDataSize, wszText, STREAMIN_BUFFER_SIZE);
|
nWideChars = MultiByteToWideChar(CP_ACP, 0, stream->buffer, stream->dwSize, wszText, STREAMIN_BUFFER_SIZE);
|
||||||
|
pText = wszText;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
nWideChars = nDataSize>>1;
|
{
|
||||||
ME_InsertTextFromCursor(editor, 0, wszText, nWideChars, style);
|
nWideChars = stream->dwSize >> 1;
|
||||||
if (nDataSize<STREAMIN_BUFFER_SIZE)
|
pText = (WCHAR *)stream->buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
ME_InsertTextFromCursor(editor, 0, pText, nWideChars, style);
|
||||||
|
if (stream->dwSize < STREAMIN_BUFFER_SIZE)
|
||||||
break;
|
break;
|
||||||
} while(1);
|
} while(1);
|
||||||
ME_CommitUndo(editor);
|
ME_CommitUndo(editor);
|
||||||
|
@ -428,6 +432,16 @@ void ME_RTFReadHook(RTF_Info *info) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
ME_StreamInFill(ME_InStream *stream)
|
||||||
|
{
|
||||||
|
stream->editstream->dwError = stream->editstream->pfnCallback(stream->editstream->dwCookie,
|
||||||
|
stream->buffer,
|
||||||
|
sizeof(stream->buffer),
|
||||||
|
&stream->dwSize);
|
||||||
|
stream->dwUsed = 0;
|
||||||
|
}
|
||||||
|
|
||||||
static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stream)
|
static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stream)
|
||||||
{
|
{
|
||||||
RTF_Info parser;
|
RTF_Info parser;
|
||||||
|
@ -435,6 +449,7 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
|
||||||
int from, to, to2, nUndoMode;
|
int from, to, to2, nUndoMode;
|
||||||
ME_UndoItem *pUI;
|
ME_UndoItem *pUI;
|
||||||
int nEventMask = editor->nEventMask;
|
int nEventMask = editor->nEventMask;
|
||||||
|
ME_InStream inStream;
|
||||||
|
|
||||||
TRACE("%p %p\n", stream, editor->hWnd);
|
TRACE("%p %p\n", stream, editor->hWnd);
|
||||||
editor->nEventMask = 0;
|
editor->nEventMask = 0;
|
||||||
|
@ -457,37 +472,60 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre
|
||||||
|
|
||||||
nUndoMode = editor->nUndoMode;
|
nUndoMode = editor->nUndoMode;
|
||||||
editor->nUndoMode = umIgnore;
|
editor->nUndoMode = umIgnore;
|
||||||
if (format & SF_RTF) {
|
|
||||||
/* setup the RTF parser */
|
|
||||||
memset(&parser, 0, sizeof parser);
|
|
||||||
RTFSetEditStream(&parser, stream);
|
|
||||||
parser.rtfFormat = format&(SF_TEXT|SF_RTF);
|
|
||||||
parser.hwndEdit = editor->hWnd;
|
|
||||||
parser.editor = editor;
|
|
||||||
parser.style = style;
|
|
||||||
WriterInit(&parser);
|
|
||||||
RTFInit(&parser);
|
|
||||||
RTFSetReadHook(&parser, ME_RTFReadHook);
|
|
||||||
BeginFile(&parser);
|
|
||||||
|
|
||||||
/* do the parsing */
|
inStream.editstream = stream;
|
||||||
RTFRead(&parser);
|
inStream.editstream->dwError = 0;
|
||||||
RTFFlushOutputBuffer(&parser);
|
inStream.dwSize = 0;
|
||||||
RTFDestroy(&parser);
|
inStream.dwUsed = 0;
|
||||||
|
|
||||||
style = parser.style;
|
if (format & SF_RTF)
|
||||||
}
|
|
||||||
else if (format & SF_TEXT)
|
|
||||||
ME_StreamInText(editor, format, stream, style);
|
|
||||||
else
|
|
||||||
ERR("EM_STREAMIN without SF_TEXT or SF_RTF\n");
|
|
||||||
ME_GetSelection(editor, &to, &to2);
|
|
||||||
/* put the cursor at the top */
|
|
||||||
if (!(format & SFF_SELECTION))
|
|
||||||
SendMessageA(editor->hWnd, EM_SETSEL, 0, 0);
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
/* FIXME where to put cursor now ? */
|
/* Check if it's really RTF, and if it is not, use plain text */
|
||||||
|
ME_StreamInFill(&inStream);
|
||||||
|
if (!inStream.editstream->dwError)
|
||||||
|
{
|
||||||
|
if (strncmp(inStream.buffer, "{\\rtf1", 6) && strncmp(inStream.buffer, "{\\urtf", 6))
|
||||||
|
{
|
||||||
|
format &= ~SF_RTF;
|
||||||
|
format |= SF_TEXT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!inStream.editstream->dwError)
|
||||||
|
{
|
||||||
|
if (format & SF_RTF) {
|
||||||
|
/* setup the RTF parser */
|
||||||
|
memset(&parser, 0, sizeof parser);
|
||||||
|
RTFSetEditStream(&parser, &inStream);
|
||||||
|
parser.rtfFormat = format&(SF_TEXT|SF_RTF);
|
||||||
|
parser.hwndEdit = editor->hWnd;
|
||||||
|
parser.editor = editor;
|
||||||
|
parser.style = style;
|
||||||
|
WriterInit(&parser);
|
||||||
|
RTFInit(&parser);
|
||||||
|
RTFSetReadHook(&parser, ME_RTFReadHook);
|
||||||
|
BeginFile(&parser);
|
||||||
|
|
||||||
|
/* do the parsing */
|
||||||
|
RTFRead(&parser);
|
||||||
|
RTFFlushOutputBuffer(&parser);
|
||||||
|
RTFDestroy(&parser);
|
||||||
|
|
||||||
|
style = parser.style;
|
||||||
|
}
|
||||||
|
else if (format & SF_TEXT)
|
||||||
|
ME_StreamInText(editor, format, &inStream, style);
|
||||||
|
else
|
||||||
|
ERR("EM_STREAMIN without SF_TEXT or SF_RTF\n");
|
||||||
|
ME_GetSelection(editor, &to, &to2);
|
||||||
|
/* put the cursor at the top */
|
||||||
|
if (!(format & SFF_SELECTION))
|
||||||
|
SendMessageA(editor->hWnd, EM_SETSEL, 0, 0);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* FIXME where to put cursor now ? */
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
editor->nUndoMode = nUndoMode;
|
editor->nUndoMode = nUndoMode;
|
||||||
|
|
|
@ -213,6 +213,7 @@ void ME_Redo(ME_TextEditor *editor);
|
||||||
void ME_EmptyUndoStack(ME_TextEditor *editor);
|
void ME_EmptyUndoStack(ME_TextEditor *editor);
|
||||||
int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int nStart, int nChars, BOOL bCRLF);
|
int ME_GetTextW(ME_TextEditor *editor, WCHAR *buffer, int nStart, int nChars, BOOL bCRLF);
|
||||||
ME_DisplayItem *ME_FindItemAtOffset(ME_TextEditor *editor, ME_DIType nItemType, int nOffset, int *nItemOffset);
|
ME_DisplayItem *ME_FindItemAtOffset(ME_TextEditor *editor, ME_DIType nItemType, int nOffset, int *nItemOffset);
|
||||||
|
void ME_StreamInFill(ME_InStream *stream);
|
||||||
|
|
||||||
extern int me_debug;
|
extern int me_debug;
|
||||||
extern HANDLE me_heap;
|
extern HANDLE me_heap;
|
||||||
|
|
|
@ -197,6 +197,18 @@ typedef struct tagME_FontTableItem {
|
||||||
WCHAR *szFaceName;
|
WCHAR *szFaceName;
|
||||||
} ME_FontTableItem;
|
} ME_FontTableItem;
|
||||||
|
|
||||||
|
|
||||||
|
#define STREAMIN_BUFFER_SIZE 4096 /* M$ compatibility */
|
||||||
|
|
||||||
|
struct tagME_InStream {
|
||||||
|
EDITSTREAM *editstream;
|
||||||
|
DWORD dwSize;
|
||||||
|
DWORD dwUsed;
|
||||||
|
BYTE buffer[STREAMIN_BUFFER_SIZE];
|
||||||
|
};
|
||||||
|
typedef struct tagME_InStream ME_InStream;
|
||||||
|
|
||||||
|
|
||||||
#define STREAMOUT_BUFFER_SIZE 4096
|
#define STREAMOUT_BUFFER_SIZE 4096
|
||||||
#define STREAMOUT_FONTTBL_SIZE 8192
|
#define STREAMOUT_FONTTBL_SIZE 8192
|
||||||
#define STREAMOUT_COLORTBL_SIZE 1024
|
#define STREAMOUT_COLORTBL_SIZE 1024
|
||||||
|
|
|
@ -123,41 +123,35 @@ static inline void RTFFree(void *p)
|
||||||
int _RTFGetChar(RTF_Info *info)
|
int _RTFGetChar(RTF_Info *info)
|
||||||
{
|
{
|
||||||
int ch;
|
int ch;
|
||||||
|
ME_InStream *stream = info->stream;
|
||||||
|
|
||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
|
|
||||||
/* if the last buffer wasn't full, it's EOF */
|
/* if the last buffer wasn't full, it's EOF */
|
||||||
if (info->dwInputSize > 0 &&
|
if (stream->dwSize > 0 && stream->dwSize == stream->dwUsed
|
||||||
info->dwInputSize == info->dwInputUsed &&
|
&& stream->dwSize < sizeof(stream->buffer))
|
||||||
info->dwInputSize < sizeof(info->InputBuffer))
|
|
||||||
return EOF;
|
return EOF;
|
||||||
if (info->dwInputSize <= info->dwInputUsed)
|
if (stream->dwSize <= stream->dwUsed)
|
||||||
{
|
{
|
||||||
long count = 0;
|
ME_StreamInFill(stream);
|
||||||
info->editstream.dwError = info->editstream.pfnCallback(info->editstream.dwCookie,
|
|
||||||
info->InputBuffer, sizeof(info->InputBuffer), &count);
|
|
||||||
/* if error, it's EOF */
|
/* if error, it's EOF */
|
||||||
if (info->editstream.dwError)
|
if (stream->editstream->dwError)
|
||||||
return EOF;
|
return EOF;
|
||||||
/* if no bytes read, it's EOF */
|
/* if no bytes read, it's EOF */
|
||||||
if (count == 0)
|
if (stream->dwSize == 0)
|
||||||
return EOF;
|
return EOF;
|
||||||
info->dwInputSize = count;
|
|
||||||
info->dwInputUsed = 0;
|
|
||||||
}
|
}
|
||||||
ch = info->InputBuffer[info->dwInputUsed++];
|
ch = stream->buffer[stream->dwUsed++];
|
||||||
if (!ch)
|
if (!ch)
|
||||||
return EOF;
|
return EOF;
|
||||||
return ch;
|
return ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RTFSetEditStream(RTF_Info *info, EDITSTREAM *es)
|
void RTFSetEditStream(RTF_Info *info, ME_InStream *stream)
|
||||||
{
|
{
|
||||||
TRACE("\n");
|
TRACE("\n");
|
||||||
|
|
||||||
info->editstream.dwCookie = es->dwCookie;
|
info->stream = stream;
|
||||||
info->editstream.dwError = es->dwError;
|
|
||||||
info->editstream.pfnCallback = es->pfnCallback;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
|
@ -1078,10 +1078,7 @@ struct _RTF_Info {
|
||||||
char *inputName;
|
char *inputName;
|
||||||
char *outputName;
|
char *outputName;
|
||||||
|
|
||||||
EDITSTREAM editstream;
|
ME_InStream *stream;
|
||||||
char InputBuffer[0x1000];
|
|
||||||
DWORD dwInputSize;
|
|
||||||
DWORD dwInputUsed;
|
|
||||||
|
|
||||||
/* edit window to output to */
|
/* edit window to output to */
|
||||||
HWND hwndEdit;
|
HWND hwndEdit;
|
||||||
|
@ -1155,7 +1152,7 @@ void RTFMsg (RTF_Info *, const char *fmt, ...);
|
||||||
void RTFPanic (RTF_Info *, const char *fmt, ...);
|
void RTFPanic (RTF_Info *, const char *fmt, ...);
|
||||||
|
|
||||||
void RTFFlushOutputBuffer( RTF_Info *info );
|
void RTFFlushOutputBuffer( RTF_Info *info );
|
||||||
void RTFSetEditStream(RTF_Info *, EDITSTREAM *es);
|
void RTFSetEditStream(RTF_Info *info, ME_InStream *stream);
|
||||||
|
|
||||||
void WriterInit (RTF_Info *);
|
void WriterInit (RTF_Info *);
|
||||||
int BeginFile (RTF_Info *);
|
int BeginFile (RTF_Info *);
|
||||||
|
|
Loading…
Reference in New Issue