RICHED20: RTF export improvements
Phil Krylov
phil at newstar.rinet.ru
Wed Mar 16 13:26:23 CST 2005
ChangeLog:
Improved RTF export.
Patch:
--- writer.c 15 Mar 2005 15:40:52 -0000 1.2
+++ writer.c 16 Mar 2005 19:11:07 -0000
@@ -23,6 +23,10 @@
WINE_DEFAULT_DEBUG_CHANNEL(richedit);
+static BOOL
+ME_StreamOutRTFText(ME_TextEditor *editor, WCHAR *text, LONG nChars);
+
+
static void
ME_StreamOutInit(ME_TextEditor *editor, EDITSTREAM *stream)
{
@@ -226,19 +230,17 @@ ME_StreamOutRTFFontAndColorTbl(ME_TextEd
return FALSE;
for (i = 0; i < editor->pStream->nFontTblLen; i++) {
- char szFaceName[LF_FACESIZE];
-
- /* FIXME: Use ME_StreamOutText to emit the font name */
- WideCharToMultiByte(editor->pStream->nCodePage, 0, table[i].szFaceName, -1,
- szFaceName, LF_FACESIZE, NULL, NULL);
if (table[i].bCharSet) {
- if (!ME_StreamOutPrint(editor, "{\\f%u\\fcharset%u %s;}\r\n",
- i, table[i].bCharSet, szFaceName))
+ if (!ME_StreamOutPrint(editor, "{\\f%u\\fcharset%u ", i, table[i].bCharSet))
return FALSE;
} else {
- if (!ME_StreamOutPrint(editor, "{\\f%u %s;}\r\n", i, szFaceName))
+ if (!ME_StreamOutPrint(editor, "{\\f%u ", i))
return FALSE;
}
+ if (!ME_StreamOutRTFText(editor, table[i].szFaceName, -1))
+ return FALSE;
+ if (!ME_StreamOutPrint(editor, ";}\r\n"))
+ return FALSE;
}
if (!ME_StreamOutPrint(editor, "}"))
return FALSE;
@@ -265,30 +267,134 @@ ME_StreamOutRTFFontAndColorTbl(ME_TextEd
static BOOL
ME_StreamOutRTFParaProps(ME_TextEditor *editor, ME_DisplayItem *para)
{
- char *keyword = NULL;
+ PARAFORMAT2 *fmt = para->member.para.pFmt;
+ char props[STREAMOUT_BUFFER_SIZE] = "";
+ int i;
/* TODO: Don't emit anything if the last PARAFORMAT2 is inherited */
if (!ME_StreamOutPrint(editor, "\\pard"))
return FALSE;
-
- switch (para->member.para.pFmt->wAlignment) {
- case PFA_LEFT:
- /* Default alignment: not emitted */
- break;
- case PFA_RIGHT:
- keyword = "\\qr";
- break;
- case PFA_CENTER:
- keyword = "\\qc";
- break;
- case PFA_JUSTIFY:
- keyword = "\\qj";
- break;
+
+ /* TODO: PFM_BORDER. M$ does not emit any keywords for these properties, and
+ * when streaming border keywords in, PFM_BORDER is set, but wBorder field is
+ * set very different from the documentation.
+ * (Tested with RichEdit 5.50.25.0601) */
+
+ if (fmt->dwMask & PFM_ALIGNMENT) {
+ switch (fmt->wAlignment) {
+ case PFA_LEFT:
+ /* Default alignment: not emitted */
+ break;
+ case PFA_RIGHT:
+ strcat(props, "\\qr");
+ break;
+ case PFA_CENTER:
+ strcat(props, "\\qc");
+ break;
+ case PFA_JUSTIFY:
+ strcat(props, "\\qj");
+ break;
+ }
+ }
+
+ if (fmt->dwMask & PFM_LINESPACING) {
+ /* FIXME: MSDN says that the bLineSpacingRule field is controlled by the
+ * PFM_SPACEAFTER flag. Is that true? I don't believe so. */
+ switch (fmt->bLineSpacingRule) {
+ case 0: /* Single spacing */
+ strcat(props, "\\sl-240\\slmult1");
+ break;
+ case 1: /* 1.5 spacing */
+ strcat(props, "\\sl-360\\slmult1");
+ break;
+ case 2: /* Double spacing */
+ strcat(props, "\\sl-480\\slmult1");
+ break;
+ case 3:
+ sprintf(props + strlen(props), "\\sl%ld\\slmult0", fmt->dyLineSpacing);
+ break;
+ case 4:
+ sprintf(props + strlen(props), "\\sl-%ld\\slmult0", fmt->dyLineSpacing);
+ break;
+ case 5:
+ sprintf(props + strlen(props), "\\sl-%ld\\slmult1", fmt->dyLineSpacing * 240 / 20);
+ break;
+ }
+ }
+
+ if (fmt->dwMask & PFM_DONOTHYPHEN && fmt->wEffects & PFE_DONOTHYPHEN)
+ strcat(props, "\\hyph0");
+ if (fmt->dwMask & PFM_KEEP && fmt->wEffects & PFE_KEEP)
+ strcat(props, "\\keep");
+ if (fmt->dwMask & PFM_KEEPNEXT && fmt->wEffects & PFE_KEEPNEXT)
+ strcat(props, "\\keepn");
+ if (fmt->dwMask & PFM_NOLINENUMBER && fmt->wEffects & PFE_NOLINENUMBER)
+ strcat(props, "\\noline");
+ if (fmt->dwMask & PFM_NOWIDOWCONTROL && fmt->wEffects & PFE_NOWIDOWCONTROL)
+ strcat(props, "\\nowidctlpar");
+ if (fmt->dwMask & PFM_PAGEBREAKBEFORE && fmt->wEffects & PFE_PAGEBREAKBEFORE)
+ strcat(props, "\\pagebb");
+ if (fmt->dwMask & PFM_RTLPARA && fmt->wEffects & PFE_RTLPARA)
+ strcat(props, "\\rtlpar");
+ if (fmt->dwMask & PFM_SIDEBYSIDE && fmt->wEffects & PFE_SIDEBYSIDE)
+ strcat(props, "\\sbys");
+ if (fmt->dwMask & PFM_TABLE && fmt->dwMask & PFE_TABLE)
+ strcat(props, "\\intbl");
+
+ if (fmt->dwMask & PFM_OFFSET)
+ sprintf(props + strlen(props), "\\li%ld", fmt->dxOffset);
+ if (fmt->dwMask & PFM_OFFSETINDENT || fmt->dwMask & PFM_STARTINDENT)
+ sprintf(props + strlen(props), "\\fi%ld", fmt->dxStartIndent);
+ if (fmt->dwMask & PFM_RIGHTINDENT)
+ sprintf(props + strlen(props), "\\ri%ld", fmt->dxRightIndent);
+ if (fmt->dwMask & PFM_SPACEAFTER)
+ sprintf(props + strlen(props), "\\sa%ld", fmt->dySpaceAfter);
+ if (fmt->dwMask & PFM_SPACEBEFORE)
+ sprintf(props + strlen(props), "\\sb%ld", fmt->dySpaceBefore);
+ if (fmt->dwMask & PFM_STYLE)
+ sprintf(props + strlen(props), "\\s%d", fmt->sStyle);
+
+ if (fmt->dwMask & PFM_TABSTOPS) {
+ static const char *leader[6] = { "", "\\tldot", "\\tlhyph", "\\tlul", "\\tlth", "\\tleq" };
+
+ for (i = 0; i < fmt->cTabCount; i++) {
+ switch ((fmt->rgxTabs[i] >> 24) & 0xF) {
+ case 1:
+ strcat(props, "\\tqc");
+ break;
+ case 2:
+ strcat(props, "\\tqr");
+ break;
+ case 3:
+ strcat(props, "\\tqdec");
+ break;
+ case 4:
+ /* Word bar tab (vertical bar). Handled below */
+ break;
+ }
+ if (fmt->rgxTabs[i] >> 28 <= 5)
+ strcat(props, leader[fmt->rgxTabs[i] >> 28]);
+ }
}
- if (keyword && !ME_StreamOutPrint(editor, keyword))
+
+
+ if (fmt->dwMask & PFM_SHADING) {
+ static const char *style[16] = { "", "\\bgdkhoriz", "\\bgdkvert", "\\bgdkfdiag",
+ "\\bgdkbdiag", "\\bgdkcross", "\\bgdkdcross",
+ "\\bghoriz", "\\bgvert", "\\bgfdiag",
+ "\\bgbdiag", "\\bgcross", "\\bgdcross",
+ "", "", "" };
+ if (fmt->wShadingWeight)
+ sprintf(props + strlen(props), "\\shading%d", fmt->wShadingWeight);
+ if (fmt->wShadingStyle & 0xF)
+ strcat(props, style[fmt->wShadingStyle & 0xF]);
+ sprintf(props + strlen(props), "\\cfpat%d\\cbpat%d",
+ (fmt->wShadingStyle >> 4) & 0xF, (fmt->wShadingStyle >> 8) & 0xF);
+ }
+
+ if (*props && !ME_StreamOutPrint(editor, props))
return FALSE;
- /* TODO: Other properties */
return TRUE;
}
@@ -355,7 +461,7 @@ ME_StreamOutRTFCharProps(ME_TextEditor *
/* TODO: CFM_REVISED CFM_REVAUTHOR - probably using rsidtbl? */
if (fmt->dwMask & CFM_SHADOW && fmt->dwEffects & CFE_SHADOW)
strcat(props, "\\shad");
- if (fmt->dwMask & CFM_SIZE && fmt->yHeight / 10 != 24)
+ if (fmt->dwMask & CFM_SIZE)
sprintf(props + strlen(props), "\\fs%ld", fmt->yHeight / 10);
if (fmt->dwMask & CFM_SMALLCAPS && fmt->dwEffects & CFE_SMALLCAPS)
strcat(props, "\\scaps");
@@ -430,7 +536,10 @@ ME_StreamOutRTFText(ME_TextEditor *edito
char buffer[STREAMOUT_BUFFER_SIZE];
int pos = 0;
int fit, i;
-
+
+ if (nChars == -1)
+ nChars = lstrlenW(text);
+
while (nChars) {
if (editor->pStream->nCodePage == CP_UTF8) {
/* 6 is the maximum character length in UTF-8 */
More information about the wine-patches
mailing list