Made RTF reader and writer handle codepages mostly similar to the

original riched20.dll.
This commit is contained in:
Phil Krylov 2005-03-22 16:41:36 +00:00 committed by Alexandre Julliard
parent aa6367400a
commit 0fdbec319b
5 changed files with 49 additions and 25 deletions

View File

@ -336,7 +336,8 @@ void ME_RTFCharAttrHook(RTF_Info *info)
{
MultiByteToWideChar(CP_ACP, 0, f->rtfFName, -1, fmt.szFaceName, sizeof(fmt.szFaceName)/sizeof(WCHAR));
fmt.szFaceName[sizeof(fmt.szFaceName)/sizeof(WCHAR)-1] = '\0';
fmt.dwMask = CFM_FACE;
fmt.bCharSet = f->rtfFCharSet;
fmt.dwMask = CFM_FACE | CFM_CHARSET;
}
}
break;

View File

@ -211,6 +211,7 @@ typedef struct tagME_OutStream {
UINT nColorTblLen;
COLORREF colortbl[STREAMOUT_COLORTBL_SIZE];
UINT nDefaultFont;
UINT nDefaultCodePage;
} ME_OutStream;
typedef struct tagME_FontCacheItem

View File

@ -260,8 +260,7 @@ void RTFInit(RTF_Info *info)
RTFDestroyAttrs(info);
info->ansiCodePage = 1252; /* Latin-1 */
info->ansiCodePage = 1252; /* Latin-1; actually unused */
info->unicodeLength = 1; /* \uc1 is the default */
info->codePage = info->ansiCodePage;
@ -555,14 +554,15 @@ static void _RTFGetToken(RTF_Info *info)
}
static int
int
RTFCharSetToCodePage(RTF_Info *info, int charset)
{
switch (charset)
{
case ANSI_CHARSET:
return 1252;
case DEFAULT_CHARSET:
return info->ansiCodePage;
return CP_ACP;
case SYMBOL_CHARSET:
return CP_SYMBOL;
case MAC_CHARSET:
@ -605,7 +605,7 @@ RTFCharSetToCodePage(RTF_Info *info, int charset)
/* FIXME: TranslateCharsetInfo does not work as good as it
* should, so let's use it only when all else fails */
if (!TranslateCharsetInfo(&n, &csi, TCI_SRCCHARSET))
RTFMsg(info,"%s: unknown charset %u\n", __FUNCTION__, charset);
RTFMsg(info, "%s: unknown charset %u\n", __FUNCTION__, charset);
else
return csi.ciACP;
}
@ -915,10 +915,10 @@ static void ReadFontTbl(RTF_Info *info)
fp->rtfFAltName = NULL;
fp->rtfFNum = -1;
fp->rtfFFamily = 0;
fp->rtfFCharSet = 0;
fp->rtfFCharSet = DEFAULT_CHARSET; /* 1 */
fp->rtfFPitch = 0;
fp->rtfFType = 0;
fp->rtfFCodePage = 0;
fp->rtfFCodePage = CP_ACP;
while (info->rtfClass != rtfEOF
&& !RTFCheckCM (info, rtfText, ';')
@ -2407,13 +2407,9 @@ int RTFHexToChar(int i)
/* ---------------------------------------------------------------------- */
/*
* Print message. Default is to send message to stderr
* but this may be overridden with RTFSetMsgProc().
* Print message.
*
* Message should include linefeeds as necessary. If the default
* function is overridden, the overriding function may want to
* map linefeeds to another line ending character or sequence if
* the host system doesn't use linefeeds.
* Message should include linefeeds as necessary.
*/
@ -2549,7 +2545,10 @@ CharAttr(RTF_Info *info)
case rtfFontNum:
font = RTFGetFont(info, info->rtfParam);
if (font)
info->codePage = font->rtfFCodePage;
{
if (info->ansiCodePage != CP_UTF8)
info->codePage = font->rtfFCodePage;
}
else
RTFMsg(info, "unknown font %d\n", info->rtfParam);
break;

View File

@ -1160,4 +1160,6 @@ void RTFSetEditStream(RTF_Info *, EDITSTREAM *es);
void WriterInit (RTF_Info *);
int BeginFile (RTF_Info *);
int RTFCharSetToCodePage(RTF_Info *info, int charset);
#endif

View File

@ -19,6 +19,7 @@
*/
#include "editor.h"
#include "rtf.h"
WINE_DEFAULT_DEBUG_CHANNEL(richedit);
@ -149,6 +150,10 @@ ME_StreamOutRTFHeader(ME_TextEditor *editor, int dwFormat)
}
} else {
cCharSet = "ansi";
/* TODO: If the original document contained an \ansicpg value, retain it.
* Otherwise, M$ richedit emits a codepage number determined from the
* charset of the default font here. Anyway, this value is not used by
* the reader... */
nCodePage = GetACP();
}
if (nCodePage == CP_UTF8)
@ -159,7 +164,7 @@ ME_StreamOutRTFHeader(ME_TextEditor *editor, int dwFormat)
if (!success)
return FALSE;
editor->pStream->nCodePage = nCodePage;
editor->pStream->nDefaultCodePage = nCodePage;
/* FIXME: This should be a document property */
/* TODO: handle SFF_PLAINRTF */
@ -187,7 +192,7 @@ ME_StreamOutRTFFontAndColorTbl(ME_TextEditor *editor, ME_DisplayItem *pFirstRun,
if (fmt->dwMask & CFM_FACE) {
WCHAR *face = fmt->szFaceName;
BYTE bCharSet = fmt->bCharSet;
BYTE bCharSet = (fmt->dwMask & CFM_CHARSET) ? fmt->bCharSet : DEFAULT_CHARSET;
for (i = 0; i < editor->pStream->nFontTblLen; i++)
if (table[i].bCharSet == bCharSet
@ -230,7 +235,7 @@ ME_StreamOutRTFFontAndColorTbl(ME_TextEditor *editor, ME_DisplayItem *pFirstRun,
return FALSE;
for (i = 0; i < editor->pStream->nFontTblLen; i++) {
if (table[i].bCharSet) {
if (table[i].bCharSet != DEFAULT_CHARSET) {
if (!ME_StreamOutPrint(editor, "{\\f%u\\fcharset%u ", i, table[i].bCharSet))
return FALSE;
} else {
@ -520,7 +525,19 @@ ME_StreamOutRTFCharProps(ME_TextEditor *editor, CHARFORMAT2W *fmt)
break;
}
if (i < editor->pStream->nFontTblLen && i != editor->pStream->nDefaultFont)
{
sprintf(props + strlen(props), "\\f%u", i);
/* In UTF-8 mode, charsets/codepages are not used */
if (editor->pStream->nDefaultCodePage != CP_UTF8)
{
if (editor->pStream->fonttbl[i].bCharSet == DEFAULT_CHARSET)
editor->pStream->nCodePage = editor->pStream->nDefaultCodePage;
else
editor->pStream->nCodePage = RTFCharSetToCodePage(NULL,
editor->pStream->fonttbl[i].bCharSet);
}
}
}
if (*props)
strcat(props, " ");
@ -541,7 +558,8 @@ ME_StreamOutRTFText(ME_TextEditor *editor, WCHAR *text, LONG nChars)
nChars = lstrlenW(text);
while (nChars) {
if (editor->pStream->nCodePage == CP_UTF8) {
/* In UTF-8 mode, font charsets are not used. */
if (editor->pStream->nDefaultCodePage == CP_UTF8) {
/* 6 is the maximum character length in UTF-8 */
fit = min(nChars, STREAMOUT_BUFFER_SIZE / 6);
WideCharToMultiByte(CP_UTF8, 0, text, fit, buffer, STREAMOUT_BUFFER_SIZE,
@ -565,22 +583,25 @@ ME_StreamOutRTFText(ME_TextEditor *editor, WCHAR *text, LONG nChars)
nChars--;
} else {
BOOL unknown;
BYTE letter[2];
BYTE letter[3];
int nBytes, i;
WideCharToMultiByte(editor->pStream->nCodePage, 0, text, 1, letter, 2,
NULL, &unknown);
nBytes = WideCharToMultiByte(editor->pStream->nCodePage, 0, text, 1,
letter, 3, NULL, &unknown);
if (unknown)
pos += sprintf(buffer + pos, "\\u%d?", (int)*text);
else if (*letter < 128) {
if (*letter == '{' || *letter == '}' || *letter == '\\')
buffer[pos++] = '\\';
buffer[pos++] = *letter;
} else
pos += sprintf(buffer + pos, "\\'%02x", *letter);
} else {
for (i = 0; i < nBytes; i++)
pos += sprintf(buffer + pos, "\\'%02x", letter[i]);
}
text++;
nChars--;
}
if (pos >= STREAMOUT_BUFFER_SIZE - 10) {
if (pos >= STREAMOUT_BUFFER_SIZE - 11) {
if (!ME_StreamOutMove(editor, buffer, pos))
return FALSE;
pos = 0;