RICHEDIT: RTF codepage handling fixes
Phil Krylov
phil at newstar.rinet.ru
Mon Mar 21 15:28:23 CST 2005
ChangeLog:
Made RTF reader and writer handle codepages mostly similar to the original
riched20.dll.
Patch:
Index: dlls/riched20/editor.c
===================================================================
RCS file: /home/wine/wine/dlls/riched20/editor.c,v
retrieving revision 1.19
diff -p -u -r1.19 editor.c
--- dlls/riched20/editor.c 21 Mar 2005 10:52:26 -0000 1.19
+++ dlls/riched20/editor.c 21 Mar 2005 21:14:40 -0000
@@ -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;
Index: dlls/riched20/editstr.h
===================================================================
RCS file: /home/wine/wine/dlls/riched20/editstr.h,v
retrieving revision 1.7
diff -p -u -r1.7 editstr.h
--- dlls/riched20/editstr.h 21 Mar 2005 10:27:24 -0000 1.7
+++ dlls/riched20/editstr.h 21 Mar 2005 21:14:41 -0000
@@ -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
Index: dlls/riched20/reader.c
===================================================================
RCS file: /home/wine/wine/dlls/riched20/reader.c,v
retrieving revision 1.10
diff -p -u -r1.10 reader.c
--- dlls/riched20/reader.c 21 Mar 2005 11:24:38 -0000 1.10
+++ dlls/riched20/reader.c 21 Mar 2005 21:14:42 -0000
@@ -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
/* 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;
Index: dlls/riched20/rtf.h
===================================================================
RCS file: /home/wine/wine/dlls/riched20/rtf.h,v
retrieving revision 1.8
diff -p -u -r1.8 rtf.h
--- dlls/riched20/rtf.h 21 Mar 2005 11:24:38 -0000 1.8
+++ dlls/riched20/rtf.h 21 Mar 2005 21:14:42 -0000
@@ -1160,4 +1160,6 @@ void RTFSetEditStream(RTF_Info *, EDITST
void WriterInit (RTF_Info *);
int BeginFile (RTF_Info *);
+int RTFCharSetToCodePage(RTF_Info *info, int charset);
+
#endif
Index: dlls/riched20/writer.c
===================================================================
RCS file: /home/wine/wine/dlls/riched20/writer.c,v
retrieving revision 1.3
diff -p -u -r1.3 writer.c
--- dlls/riched20/writer.c 16 Mar 2005 20:18:11 -0000 1.3
+++ dlls/riched20/writer.c 21 Mar 2005 21:14:43 -0000
@@ -19,6 +19,7 @@
*/
#include "editor.h"
+#include "rtf.h"
WINE_DEFAULT_DEBUG_CHANNEL(richedit);
@@ -149,6 +150,10 @@ ME_StreamOutRTFHeader(ME_TextEditor *edi
}
} 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 *edi
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_TextEd
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_TextEd
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 *
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 *edito
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 *edito
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;
More information about the wine-patches
mailing list