diff --git a/dll/win32/riched20/editor.c b/dll/win32/riched20/editor.c index b2a0f78200c..ca85ce40a3f 100644 --- a/dll/win32/riched20/editor.c +++ b/dll/win32/riched20/editor.c @@ -1521,6 +1521,61 @@ static void ME_RTFReadParnumGroup( RTF_Info *info ) RTFRouteToken( info ); /* feed "}" back to router */ } +static void ME_RTFReadPntextGroup( RTF_Info *info ) +{ + int level = 1; + WCHAR buf[256]; + int buf_len = 0; + + ME_DestroyString( info->pntext ); + info->pntext = NULL; + + for (;;) + { + RTFGetToken( info ); + + if (info->rtfClass == rtfEOF) + return; + + if (RTFCheckCM( info, rtfGroup, rtfBeginGroup )) + { + level++; + continue; + } + + if (RTFCheckCM( info, rtfGroup, rtfEndGroup )) + { + level--; + if (level == 0) break; + continue; + } + + if (buf_len >= ARRAY_SIZE(buf) - 1) + continue; + + if (info->rtfClass == rtfText) + { + buf[buf_len++] = (WCHAR)(unsigned char)info->rtfMajor; + } + else if (info->rtfClass == rtfControl && info->rtfMajor == rtfSpecialChar) + { + switch (info->rtfMinor) + { + case rtfTab: buf[buf_len++] = '\t'; break; + case rtfBullet: buf[buf_len++] = 0x2022; break; + case rtfNoBrkSpace: buf[buf_len++] = 0x00A0; break; + case rtfNoBrkHyphen:buf[buf_len++] = 0x2011; break; + case rtfOptDest: + default: break; + } + } + } + + info->pntext = ME_MakeStringN( buf, buf_len ); + + RTFRouteToken( info ); +} + static void ME_RTFReadHook(RTF_Info *info) { switch(info->rtfClass) @@ -1678,6 +1733,7 @@ static LRESULT ME_StreamIn(ME_TextEditor *editor, DWORD format, EDITSTREAM *stre RTFSetDestinationCallback(&parser, rtfPict, ME_RTFReadPictGroup); RTFSetDestinationCallback(&parser, rtfObject, ME_RTFReadObjectGroup); RTFSetDestinationCallback(&parser, rtfParNumbering, ME_RTFReadParnumGroup); + RTFSetDestinationCallback(&parser, rtfParNumText, ME_RTFReadPntextGroup); if (!parser.editor->bEmulateVersion10) /* v4.1 */ { RTFSetDestinationCallback(&parser, rtfNoNestTables, RTFSkipGroup); diff --git a/dll/win32/riched20/reader.c b/dll/win32/riched20/reader.c index 95360d8b9d4..402335d4b68 100644 --- a/dll/win32/riched20/reader.c +++ b/dll/win32/riched20/reader.c @@ -150,6 +150,7 @@ RTFDestroy(RTF_Info *info) } RTFDestroyAttrs(info); free(info->cpOutputBuffer); + ME_DestroyString( info->pntext ); while (info->tableDef) { RTFTable *tableDef = info->tableDef; @@ -252,6 +253,7 @@ void RTFInit(RTF_Info *info) info->nestingLevel = 0; info->canInheritInTbl = FALSE; info->borderType = 0; + info->pntext = NULL; memset(&info->fmt, 0, sizeof(info->fmt)); info->fmt.cbSize = sizeof(info->fmt); @@ -2498,13 +2500,42 @@ static void SpecialChar (RTF_Info *info) case rtfPage: case rtfSect: case rtfPar: + { + ME_Paragraph *para; RTFFlushOutputBuffer(info); + if ((info->fmt.dwMask & PFM_NUMBERING) && !info->pntext) + info->fmt.wNumbering = 0; + + if (info->pntext && info->pntext->nLen && + info->pntext->szData[info->pntext->nLen - 1] == '\t') + { + info->pntext->szData[--info->pntext->nLen] = 0; + if ((info->fmt.dwMask & PFM_NUMBERINGTAB) && + info->fmt.wNumberingTab == 0) + info->fmt.wNumberingTab = lDefaultTab; + } + editor_set_selection_para_fmt( info->editor, &info->fmt ); + para = info->editor->pCursors[0].para; memset(&info->fmt, 0, sizeof(info->fmt)); info->fmt.cbSize = sizeof(info->fmt); RTFPutUnicodeChar (info, '\r'); if (info->editor->bEmulateVersion10) RTFPutUnicodeChar (info, '\n'); + + if (info->pntext) + { + if (info->pntext->nLen && para->fmt.wNumbering) + { + para_num_clear( ¶->para_num ); + para->para_num.text = info->pntext; + info->pntext = NULL; + para_mark_rewrap( info->editor, para ); + } + ME_DestroyString( info->pntext ); + info->pntext = NULL; + } break; + } case rtfNoBrkSpace: RTFPutUnicodeChar (info, 0x00A0); break; diff --git a/dll/win32/riched20/rtf.h b/dll/win32/riched20/rtf.h index f2d446ac5d3..69deb28ea0c 100644 --- a/dll/win32/riched20/rtf.h +++ b/dll/win32/riched20/rtf.h @@ -1175,6 +1175,7 @@ struct _RTF_Info { int borderType; /* value corresponds to the RTFBorder constants. */ PARAFORMAT2 fmt; /* Accumulated para fmt for current paragraph. */ + ME_String *pntext; /* Explicit paragraph number text from \pntext destination. */ };