Made RTF reader and writer handle codepages mostly similar to the
original riched20.dll.
This commit is contained in:
parent
aa6367400a
commit
0fdbec319b
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue