ReactOS 0.4.16-dev-1946-g52006dd
writer.c File Reference
#include "editor.h"
#include "rtf.h"
Include dependency graph for writer.c:

Go to the source code of this file.

Classes

struct  tagME_OutStream
 

Macros

#define STREAMOUT_BUFFER_SIZE   4096
 
#define STREAMOUT_FONTTBL_SIZE   8192
 
#define STREAMOUT_COLORTBL_SIZE   1024
 
#define HEX_BYTES_PER_LINE   40
 

Typedefs

typedef struct tagME_OutStream ME_OutStream
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (richedit)
 
static BOOL ME_StreamOutRTFText (ME_OutStream *pStream, const WCHAR *text, LONG nChars)
 
static ME_OutStreamME_StreamOutInit (ME_TextEditor *editor, EDITSTREAM *stream)
 
static BOOL ME_StreamOutFlush (ME_OutStream *pStream)
 
static LONG ME_StreamOutFree (ME_OutStream *pStream)
 
static BOOL ME_StreamOutMove (ME_OutStream *pStream, const char *buffer, int len)
 
static BOOL WINAPIV ME_StreamOutPrint (ME_OutStream *pStream, const char *format,...)
 
static BOOL ME_StreamOutHexData (ME_OutStream *stream, const BYTE *data, UINT len)
 
static BOOL ME_StreamOutRTFHeader (ME_OutStream *pStream, int dwFormat)
 
static void add_font_to_fonttbl (ME_OutStream *stream, ME_Style *style)
 
static BOOL find_font_in_fonttbl (ME_OutStream *stream, CHARFORMAT2W *fmt, unsigned int *idx)
 
static void add_color_to_colortbl (ME_OutStream *stream, COLORREF color)
 
static BOOL find_color_in_colortbl (ME_OutStream *stream, COLORREF color, unsigned int *idx)
 
static BOOL stream_out_font_and_colour_tbls (ME_OutStream *pStream, ME_Run *first, ME_Run *last)
 
static BOOL stream_out_table_props (ME_TextEditor *editor, ME_OutStream *pStream, ME_Paragraph *para)
 
static BOOL stream_out_para_num (ME_OutStream *stream, ME_Paragraph *para, BOOL pn_dest)
 
static BOOL stream_out_para_props (ME_TextEditor *editor, ME_OutStream *pStream, ME_Paragraph *para)
 
static BOOL ME_StreamOutRTFCharProps (ME_OutStream *pStream, CHARFORMAT2W *fmt)
 
static BOOL stream_out_graphics (ME_TextEditor *editor, ME_OutStream *stream, ME_Run *run)
 
static BOOL ME_StreamOutRTF (ME_TextEditor *editor, ME_OutStream *pStream, const ME_Cursor *start, int nChars, int dwFormat)
 
static BOOL ME_StreamOutText (ME_TextEditor *editor, ME_OutStream *pStream, const ME_Cursor *start, int nChars, DWORD dwFormat)
 
LRESULT ME_StreamOutRange (ME_TextEditor *editor, DWORD dwFormat, const ME_Cursor *start, int nChars, EDITSTREAM *stream)
 
LRESULT ME_StreamOut (ME_TextEditor *editor, DWORD dwFormat, EDITSTREAM *stream)
 

Macro Definition Documentation

◆ HEX_BYTES_PER_LINE

#define HEX_BYTES_PER_LINE   40

Definition at line 135 of file writer.c.

◆ STREAMOUT_BUFFER_SIZE

#define STREAMOUT_BUFFER_SIZE   4096

Definition at line 26 of file writer.c.

◆ STREAMOUT_COLORTBL_SIZE

#define STREAMOUT_COLORTBL_SIZE   1024

Definition at line 28 of file writer.c.

◆ STREAMOUT_FONTTBL_SIZE

#define STREAMOUT_FONTTBL_SIZE   8192

Definition at line 27 of file writer.c.

Typedef Documentation

◆ ME_OutStream

Function Documentation

◆ add_color_to_colortbl()

static void add_color_to_colortbl ( ME_OutStream stream,
COLORREF  color 
)
static

Definition at line 280 of file writer.c.

281{
282 int i;
283
284 for (i = 1; i < stream->nColorTblLen; i++)
285 if (stream->colortbl[i] == color)
286 break;
287
288 if (i == stream->nColorTblLen && i < STREAMOUT_COLORTBL_SIZE)
289 {
290 stream->colortbl[i] = color;
291 stream->nColorTblLen++;
292 }
293}
#define STREAMOUT_COLORTBL_SIZE
Definition: writer.c:28
GLuint color
Definition: glext.h:6243
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
Definition: parse.h:23

Referenced by stream_out_font_and_colour_tbls().

◆ add_font_to_fonttbl()

static void add_font_to_fonttbl ( ME_OutStream stream,
ME_Style style 
)
static

Definition at line 231 of file writer.c.

232{
233 ME_FontTableItem *table = stream->fonttbl;
234 CHARFORMAT2W *fmt = &style->fmt;
235 WCHAR *face = fmt->szFaceName;
236 BYTE charset = (fmt->dwMask & CFM_CHARSET) ? fmt->bCharSet : DEFAULT_CHARSET;
237 int i;
238
239 if (fmt->dwMask & CFM_FACE)
240 {
241 for (i = 0; i < stream->nFontTblLen; i++)
242 if (table[i].bCharSet == charset
243 && (table[i].szFaceName == face || !wcscmp(table[i].szFaceName, face)))
244 break;
245
246 if (i == stream->nFontTblLen && i < STREAMOUT_FONTTBL_SIZE)
247 {
248 table[i].bCharSet = charset;
249 table[i].szFaceName = face;
250 stream->nFontTblLen++;
251 }
252 }
253}
Arabic default style
Definition: afstyles.h:94
CFF_Charset charset
Definition: cffcmap.c:138
WORD face[3]
Definition: mesh.c:4747
#define STREAMOUT_FONTTBL_SIZE
Definition: writer.c:27
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
if(dx< 0)
Definition: linetemp.h:194
#define CFM_CHARSET
Definition: richedit.h:358
#define CFM_FACE
Definition: richedit.h:360
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
Definition: dsound.c:943
#define DEFAULT_CHARSET
Definition: wingdi.h:384
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned char BYTE
Definition: xxhash.c:193

Referenced by stream_out_font_and_colour_tbls().

◆ find_color_in_colortbl()

static BOOL find_color_in_colortbl ( ME_OutStream stream,
COLORREF  color,
unsigned int idx 
)
static

Definition at line 295 of file writer.c.

296{
297 int i;
298
299 *idx = 0;
300 for (i = 1; i < stream->nColorTblLen; i++)
301 {
302 if (stream->colortbl[i] == color)
303 {
304 *idx = i;
305 break;
306 }
307 }
308
309 return i < stream->nFontTblLen;
310}
unsigned int idx
Definition: utils.c:41

Referenced by ME_StreamOutRTFCharProps(), and stream_out_table_props().

◆ find_font_in_fonttbl()

static BOOL find_font_in_fonttbl ( ME_OutStream stream,
CHARFORMAT2W fmt,
unsigned int idx 
)
static

Definition at line 255 of file writer.c.

256{
257 WCHAR *facename;
258 int i;
259
260 *idx = 0;
261 if (fmt->dwMask & CFM_FACE)
262 facename = fmt->szFaceName;
263 else
264 facename = stream->fonttbl[0].szFaceName;
265 for (i = 0; i < stream->nFontTblLen; i++)
266 {
267 if (facename == stream->fonttbl[i].szFaceName
268 || !wcscmp(facename, stream->fonttbl[i].szFaceName))
269 if (!(fmt->dwMask & CFM_CHARSET)
270 || fmt->bCharSet == stream->fonttbl[i].bCharSet)
271 {
272 *idx = i;
273 break;
274 }
275 }
276
277 return i < stream->nFontTblLen;
278}

Referenced by ME_StreamOutRTFCharProps(), and stream_out_para_num().

◆ ME_StreamOut()

LRESULT ME_StreamOut ( ME_TextEditor editor,
DWORD  dwFormat,
EDITSTREAM stream 
)

Definition at line 1193 of file writer.c.

1194{
1196 int nChars;
1197
1198 if (dwFormat & SFF_SELECTION) {
1199 LONG nStart, nTo;
1200 start = editor->pCursors[ME_GetSelectionOfs(editor, &nStart, &nTo)];
1201 nChars = nTo - nStart;
1202 } else {
1203 ME_SetCursorToStart(editor, &start);
1204 nChars = ME_GetTextLength(editor);
1205 /* Generate an end-of-paragraph at the end of SCF_ALL RTF output */
1206 if (dwFormat & SF_RTF)
1207 nChars++;
1208 }
1209 return ME_StreamOutRange(editor, dwFormat, &start, nChars, stream);
1210}
void ME_SetCursorToStart(ME_TextEditor *editor, ME_Cursor *cursor)
Definition: caret.c:27
int ME_GetSelectionOfs(ME_TextEditor *editor, LONG *from, LONG *to)
Definition: caret.c:42
int ME_GetTextLength(ME_TextEditor *editor)
Definition: caret.c:83
LRESULT ME_StreamOutRange(ME_TextEditor *editor, DWORD dwFormat, const ME_Cursor *start, int nChars, EDITSTREAM *stream)
Definition: writer.c:1177
GLuint start
Definition: gl.h:1545
long LONG
Definition: pedump.c:60
#define SFF_SELECTION
Definition: richedit.h:979
#define SF_RTF
Definition: richedit.h:721
ME_Cursor * pCursors
Definition: editstr.h:396

Referenced by editor_handle_message().

◆ ME_StreamOutFlush()

static BOOL ME_StreamOutFlush ( ME_OutStream pStream)
static

Definition at line 67 of file writer.c.

68{
69 LONG nWritten = 0;
70 EDITSTREAM *stream = pStream->stream;
71
72 if (pStream->pos) {
73 TRACE("sending %u bytes\n", pStream->pos);
74 nWritten = pStream->pos;
75 stream->dwError = stream->pfnCallback(stream->dwCookie, (LPBYTE)pStream->buffer,
76 pStream->pos, &nWritten);
77 TRACE("error=%lu written=%lu\n", stream->dwError, nWritten);
78 if (nWritten == 0 || stream->dwError)
79 return FALSE;
80 /* Don't resend partial chunks if nWritten < pStream->pos */
81 }
82 if (nWritten == pStream->pos)
83 pStream->written += nWritten;
84 pStream->pos = 0;
85 return TRUE;
86}
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define TRACE(s)
Definition: solgame.cpp:4
EDITSTREAM * stream
Definition: writer.c:32
UINT written
Definition: writer.c:34
char buffer[STREAMOUT_BUFFER_SIZE]
Definition: writer.c:33
unsigned char * LPBYTE
Definition: typedefs.h:53

Referenced by ME_StreamOutMove(), and ME_StreamOutRange().

◆ ME_StreamOutFree()

static LONG ME_StreamOutFree ( ME_OutStream pStream)
static

Definition at line 90 of file writer.c.

91{
92 LONG written = pStream->written;
93 TRACE("total length = %lu\n", written);
94
95 free(pStream);
96 return written;
97}
#define free
Definition: debug_ros.c:5

Referenced by ME_StreamOutRange().

◆ ME_StreamOutHexData()

static BOOL ME_StreamOutHexData ( ME_OutStream stream,
const BYTE data,
UINT  len 
)
static

Definition at line 138 of file writer.c.

139{
140
141 char line[HEX_BYTES_PER_LINE * 2 + 1];
142 UINT size, i;
143 static const char hex[] = "0123456789abcdef";
144
145 while (len)
146 {
148 for (i = 0; i < size; i++)
149 {
150 line[i * 2] = hex[(*data >> 4) & 0xf];
151 line[i * 2 + 1] = hex[*data & 0xf];
152 data++;
153 }
154 line[size * 2] = '\n';
155 if (!ME_StreamOutMove( stream, line, size * 2 + 1 ))
156 return FALSE;
157 len -= size;
158 }
159 return TRUE;
160}
#define HEX_BYTES_PER_LINE
Definition: writer.c:135
static BOOL ME_StreamOutMove(ME_OutStream *pStream, const char *buffer, int len)
Definition: writer.c:101
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLsizeiptr size
Definition: glext.h:5919
GLenum GLsizei len
Definition: glext.h:6722
int hex(char ch)
#define min(a, b)
Definition: monoChain.cc:55
unsigned int UINT
Definition: ndis.h:50
Definition: parser.c:49

Referenced by stream_out_graphics().

◆ ME_StreamOutInit()

static ME_OutStream * ME_StreamOutInit ( ME_TextEditor editor,
EDITSTREAM stream 
)
static

Definition at line 53 of file writer.c.

54{
55 ME_OutStream *pStream = calloc(1, sizeof(*pStream));
56
57 pStream->stream = stream;
58 pStream->stream->dwError = 0;
59 pStream->nColorTblLen = 1;
62 return pStream;
63}
#define CFE_AUTOCOLOR
Definition: richedit.h:414
#define CFU_UNDERLINE
Definition: richedit.h:428
#define CFE_AUTOBACKCOLOR
Definition: richedit.h:425
#define calloc
Definition: rosglue.h:14
DWORD dwEffects
Definition: richedit.h:307
BYTE bUnderlineType
Definition: richedit.h:321
DWORD dwError
Definition: richedit.h:523
CHARFORMAT2W cur_fmt
Definition: writer.c:45
UINT nColorTblLen
Definition: writer.c:38

Referenced by ME_StreamOutRange().

◆ ME_StreamOutMove()

static BOOL ME_StreamOutMove ( ME_OutStream pStream,
const char buffer,
int  len 
)
static

Definition at line 101 of file writer.c.

102{
103 while (len) {
104 int space = STREAMOUT_BUFFER_SIZE - pStream->pos;
105 int fit = min(space, len);
106
107 TRACE("%u:%u:%s\n", pStream->pos, fit, debugstr_an(buffer,fit));
108 memmove(pStream->buffer + pStream->pos, buffer, fit);
109 len -= fit;
110 buffer += fit;
111 pStream->pos += fit;
112 if (pStream->pos == STREAMOUT_BUFFER_SIZE) {
113 if (!ME_StreamOutFlush(pStream))
114 return FALSE;
115 }
116 }
117 return TRUE;
118}
static __inline const char * debugstr_an(const char *s, int n)
Definition: compat.h:55
#define STREAMOUT_BUFFER_SIZE
Definition: writer.c:26
static BOOL ME_StreamOutFlush(ME_OutStream *pStream)
Definition: writer.c:67
GLuint buffer
Definition: glext.h:5915
#define memmove(s1, s2, n)
Definition: mkisofs.h:881

Referenced by ME_StreamOutHexData(), ME_StreamOutPrint(), ME_StreamOutRTF(), ME_StreamOutRTFText(), and ME_StreamOutText().

◆ ME_StreamOutPrint()

static BOOL WINAPIV ME_StreamOutPrint ( ME_OutStream pStream,
const char format,
  ... 
)
static

Definition at line 122 of file writer.c.

123{
124 char string[STREAMOUT_BUFFER_SIZE]; /* This is going to be enough */
125 int len;
127
129 len = vsnprintf(string, sizeof(string), format, valist);
130 va_end(valist);
131
132 return ME_StreamOutMove(pStream, string, len);
133}
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
static va_list valist
Definition: printf.c:46
Definition: format.c:58
#define vsnprintf
Definition: tif_win32.c:406

Referenced by ME_StreamOutRTF(), ME_StreamOutRTFCharProps(), ME_StreamOutRTFHeader(), ME_StreamOutRTFText(), stream_out_font_and_colour_tbls(), stream_out_graphics(), stream_out_para_num(), stream_out_para_props(), and stream_out_table_props().

◆ ME_StreamOutRange()

LRESULT ME_StreamOutRange ( ME_TextEditor editor,
DWORD  dwFormat,
const ME_Cursor start,
int  nChars,
EDITSTREAM stream 
)

Definition at line 1177 of file writer.c.

1180{
1181 ME_OutStream *pStream = ME_StreamOutInit(editor, stream);
1182
1183 if (dwFormat & SF_RTF)
1184 ME_StreamOutRTF(editor, pStream, start, nChars, dwFormat);
1185 else if (dwFormat & SF_TEXT || dwFormat & SF_TEXTIZED)
1186 ME_StreamOutText(editor, pStream, start, nChars, dwFormat);
1187 if (!pStream->stream->dwError)
1188 ME_StreamOutFlush(pStream);
1189 return ME_StreamOutFree(pStream);
1190}
static LONG ME_StreamOutFree(ME_OutStream *pStream)
Definition: writer.c:90
static ME_OutStream * ME_StreamOutInit(ME_TextEditor *editor, EDITSTREAM *stream)
Definition: writer.c:53
static BOOL ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream, const ME_Cursor *start, int nChars, DWORD dwFormat)
Definition: writer.c:1119
static BOOL ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream, const ME_Cursor *start, int nChars, int dwFormat)
Definition: writer.c:995
#define SF_TEXT
Definition: richedit.h:720
#define SF_TEXTIZED
Definition: richedit.h:723

Referenced by get_rtf_text(), and ME_StreamOut().

◆ ME_StreamOutRTF()

static BOOL ME_StreamOutRTF ( ME_TextEditor editor,
ME_OutStream pStream,
const ME_Cursor start,
int  nChars,
int  dwFormat 
)
static

Definition at line 995 of file writer.c.

997{
999 ME_Paragraph *prev_para = NULL;
1000 ME_Cursor endCur = cursor;
1001
1002 ME_MoveCursorChars(editor, &endCur, nChars, TRUE);
1003
1004 if (!ME_StreamOutRTFHeader(pStream, dwFormat))
1005 return FALSE;
1006
1007 if (!stream_out_font_and_colour_tbls( pStream, cursor.run, endCur.run ))
1008 return FALSE;
1009
1010 /* TODO: stylesheet table */
1011
1012 if (!ME_StreamOutPrint(pStream, "{\\*\\generator Wine Riched20 2.0;}\r\n"))
1013 return FALSE;
1014
1015 /* TODO: information group */
1016
1017 /* TODO: document formatting properties */
1018
1019 /* FIXME: We have only one document section */
1020
1021 /* TODO: section formatting properties */
1022
1023 do
1024 {
1025 if (cursor.para != prev_para)
1026 {
1027 prev_para = cursor.para;
1028 if (!stream_out_para_props( editor, pStream, cursor.para ))
1029 return FALSE;
1030 }
1031
1032 if (cursor.run == endCur.run && !endCur.nOffset)
1033 break;
1034
1035 TRACE("flags %xh\n", cursor.run->nFlags);
1036 /* TODO: emit embedded objects */
1037 if (cursor.para->nFlags & (MEPF_ROWSTART | MEPF_ROWEND))
1038 continue;
1039 if (cursor.run->nFlags & MERF_GRAPHICS)
1040 {
1041 if (!stream_out_graphics( editor, pStream, cursor.run ))
1042 return FALSE;
1043 }
1044 else if (cursor.run->nFlags & MERF_TAB)
1045 {
1046 if (editor->bEmulateVersion10 && /* v1.0 - 3.0 */
1047 para_in_table( cursor.para ))
1048 {
1049 if (!ME_StreamOutPrint(pStream, "\\cell "))
1050 return FALSE;
1051 }
1052 else
1053 {
1054 if (!ME_StreamOutPrint(pStream, "\\tab "))
1055 return FALSE;
1056 }
1057 }
1058 else if (cursor.run->nFlags & MERF_ENDCELL)
1059 {
1060 if (pStream->nNestingLevel > 1)
1061 {
1062 if (!ME_StreamOutPrint(pStream, "\\nestcell "))
1063 return FALSE;
1064 }
1065 else
1066 {
1067 if (!ME_StreamOutPrint(pStream, "\\cell "))
1068 return FALSE;
1069 }
1070 nChars--;
1071 }
1072 else if (cursor.run->nFlags & MERF_ENDPARA)
1073 {
1074 if (!ME_StreamOutRTFCharProps( pStream, &cursor.run->style->fmt ))
1075 return FALSE;
1076
1077 if (para_in_table( cursor.para ) &&
1078 !(cursor.para->nFlags & (MEPF_ROWSTART | MEPF_ROWEND | MEPF_CELL)))
1079 {
1080 if (!ME_StreamOutPrint(pStream, "\\row\r\n"))
1081 return FALSE;
1082 }
1083 else
1084 {
1085 if (!ME_StreamOutPrint(pStream, "\\par\r\n"))
1086 return FALSE;
1087 }
1088 /* Skip as many characters as required by current line break */
1089 nChars = max(0, nChars - cursor.run->len);
1090 }
1091 else if (cursor.run->nFlags & MERF_ENDROW)
1092 {
1093 if (!ME_StreamOutPrint(pStream, "\\line\r\n"))
1094 return FALSE;
1095 nChars--;
1096 }
1097 else
1098 {
1099 int nEnd;
1100
1101 TRACE("style %p\n", cursor.run->style);
1102 if (!ME_StreamOutRTFCharProps( pStream, &cursor.run->style->fmt ))
1103 return FALSE;
1104
1105 nEnd = (cursor.run == endCur.run) ? endCur.nOffset : cursor.run->len;
1106 if (!ME_StreamOutRTFText(pStream, get_text( cursor.run, cursor.nOffset ),
1107 nEnd - cursor.nOffset))
1108 return FALSE;
1109 cursor.nOffset = 0;
1110 }
1111 } while (cursor.run != endCur.run && cursor_next_run( &cursor, TRUE ));
1112
1113 if (!ME_StreamOutMove(pStream, "}\0", 2))
1114 return FALSE;
1115 return TRUE;
1116}
#define NULL
Definition: types.h:112
int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs, BOOL final_eop)
Definition: caret.c:709
static BOOL ME_StreamOutRTFHeader(ME_OutStream *pStream, int dwFormat)
Definition: writer.c:163
static BOOL ME_StreamOutRTFCharProps(ME_OutStream *pStream, CHARFORMAT2W *fmt)
Definition: writer.c:729
static BOOL stream_out_font_and_colour_tbls(ME_OutStream *pStream, ME_Run *first, ME_Run *last)
Definition: writer.c:312
static BOOL WINAPIV ME_StreamOutPrint(ME_OutStream *pStream, const char *format,...)
Definition: writer.c:122
static BOOL stream_out_para_props(ME_TextEditor *editor, ME_OutStream *pStream, ME_Paragraph *para)
Definition: writer.c:532
static BOOL stream_out_graphics(ME_TextEditor *editor, ME_OutStream *stream, ME_Run *run)
Definition: writer.c:928
static BOOL ME_StreamOutRTFText(ME_OutStream *pStream, const WCHAR *text, LONG nChars)
Definition: writer.c:862
BOOL cursor_next_run(ME_Cursor *cursor, BOOL all_para)
Definition: run.c:30
BOOL para_in_table(ME_Paragraph *para)
Definition: para.c:122
static WCHAR * get_text(const ME_Run *run, int offset)
Definition: editor.h:41
#define MERF_TAB
Definition: editstr.h:105
#define MERF_ENDPARA
Definition: editstr.h:120
#define MERF_ENDCELL
Definition: editstr.h:107
#define MEPF_CELL
Definition: editstr.h:141
#define MERF_GRAPHICS
Definition: editstr.h:103
#define MEPF_ROWSTART
Definition: editstr.h:142
#define MEPF_ROWEND
Definition: editstr.h:143
#define MERF_ENDROW
Definition: editstr.h:122
const char cursor[]
Definition: icontest.c:13
int nOffset
Definition: editstr.h:277
ME_Run * run
Definition: editstr.h:276
UINT nNestingLevel
Definition: writer.c:44
unsigned int bEmulateVersion10
Definition: editstr.h:392
#define max(a, b)
Definition: svc.c:63

Referenced by ME_StreamOutRange().

◆ ME_StreamOutRTFCharProps()

static BOOL ME_StreamOutRTFCharProps ( ME_OutStream pStream,
CHARFORMAT2W fmt 
)
static

Definition at line 729 of file writer.c.

730{
731 char props[STREAMOUT_BUFFER_SIZE] = "";
732 unsigned int i;
733 CHARFORMAT2W *old_fmt = &pStream->cur_fmt;
734 static const struct
735 {
736 DWORD effect;
737 const char *on, *off;
738 } effects[] =
739 {
740 { CFE_ALLCAPS, "\\caps", "\\caps0" },
741 { CFE_BOLD, "\\b", "\\b0" },
742 { CFE_DISABLED, "\\disabled", "\\disabled0" },
743 { CFE_EMBOSS, "\\embo", "\\embo0" },
744 { CFE_HIDDEN, "\\v", "\\v0" },
745 { CFE_IMPRINT, "\\impr", "\\impr0" },
746 { CFE_ITALIC, "\\i", "\\i0" },
747 { CFE_OUTLINE, "\\outl", "\\outl0" },
748 { CFE_PROTECTED, "\\protect", "\\protect0" },
749 { CFE_SHADOW, "\\shad", "\\shad0" },
750 { CFE_SMALLCAPS, "\\scaps", "\\scaps0" },
751 { CFE_STRIKEOUT, "\\strike", "\\strike0" },
752 };
753
754 for (i = 0; i < ARRAY_SIZE( effects ); i++)
755 {
756 if ((old_fmt->dwEffects ^ fmt->dwEffects) & effects[i].effect)
757 strcat( props, fmt->dwEffects & effects[i].effect ? effects[i].on : effects[i].off );
758 }
759
760 if ((old_fmt->dwEffects ^ fmt->dwEffects) & CFE_AUTOBACKCOLOR ||
761 (!(fmt->dwEffects & CFE_AUTOBACKCOLOR) && old_fmt->crBackColor != fmt->crBackColor))
762 {
763 if (fmt->dwEffects & CFE_AUTOBACKCOLOR) i = 0;
764 else find_color_in_colortbl( pStream, fmt->crBackColor, &i );
765 sprintf(props + strlen(props), "\\highlight%u", i);
766 }
767 if ((old_fmt->dwEffects ^ fmt->dwEffects) & CFE_AUTOCOLOR ||
768 (!(fmt->dwEffects & CFE_AUTOCOLOR) && old_fmt->crTextColor != fmt->crTextColor))
769 {
770 if (fmt->dwEffects & CFE_AUTOCOLOR) i = 0;
771 else find_color_in_colortbl( pStream, fmt->crTextColor, &i );
772 sprintf(props + strlen(props), "\\cf%u", i);
773 }
774
775 if (old_fmt->bAnimation != fmt->bAnimation)
776 sprintf(props + strlen(props), "\\animtext%u", fmt->bAnimation);
777 if (old_fmt->wKerning != fmt->wKerning)
778 sprintf(props + strlen(props), "\\kerning%u", fmt->wKerning);
779
780 if (old_fmt->lcid != fmt->lcid)
781 {
782 /* TODO: handle SFF_PLAINRTF */
783 if (LOWORD(fmt->lcid) == 1024)
784 strcat(props, "\\noproof\\lang1024\\langnp1024\\langfe1024\\langfenp1024");
785 else
786 sprintf(props + strlen(props), "\\lang%u", LOWORD(fmt->lcid));
787 }
788
789 if (old_fmt->yOffset != fmt->yOffset)
790 {
791 if (fmt->yOffset >= 0)
792 sprintf(props + strlen(props), "\\up%ld", fmt->yOffset);
793 else
794 sprintf(props + strlen(props), "\\dn%ld", -fmt->yOffset);
795 }
796 if (old_fmt->yHeight != fmt->yHeight)
797 sprintf(props + strlen(props), "\\fs%ld", fmt->yHeight / 10);
798 if (old_fmt->sSpacing != fmt->sSpacing)
799 sprintf(props + strlen(props), "\\expnd%u\\expndtw%u", fmt->sSpacing / 5, fmt->sSpacing);
800 if ((old_fmt->dwEffects ^ fmt->dwEffects) & (CFM_SUBSCRIPT | CFM_SUPERSCRIPT))
801 {
802 if (fmt->dwEffects & CFE_SUBSCRIPT)
803 strcat(props, "\\sub");
804 else if (fmt->dwEffects & CFE_SUPERSCRIPT)
805 strcat(props, "\\super");
806 else
807 strcat(props, "\\nosupersub");
808 }
809 if ((old_fmt->dwEffects ^ fmt->dwEffects) & CFE_UNDERLINE ||
810 old_fmt->bUnderlineType != fmt->bUnderlineType)
811 {
812 BYTE type = (fmt->dwEffects & CFE_UNDERLINE) ? fmt->bUnderlineType : CFU_UNDERLINENONE;
813 switch (type)
814 {
815 case CFU_UNDERLINE:
816 strcat(props, "\\ul");
817 break;
819 strcat(props, "\\uld");
820 break;
822 strcat(props, "\\uldb");
823 break;
825 strcat(props, "\\ulw");
826 break;
827 case CFU_CF1UNDERLINE:
829 default:
830 strcat(props, "\\ulnone");
831 break;
832 }
833 }
834
835 if (wcscmp(old_fmt->szFaceName, fmt->szFaceName) ||
836 old_fmt->bCharSet != fmt->bCharSet)
837 {
838 if (find_font_in_fonttbl( pStream, fmt, &i ))
839 {
840 sprintf(props + strlen(props), "\\f%u", i);
841
842 /* In UTF-8 mode, charsets/codepages are not used */
843 if (pStream->nDefaultCodePage != CP_UTF8)
844 {
845 if (pStream->fonttbl[i].bCharSet == DEFAULT_CHARSET)
846 pStream->nCodePage = pStream->nDefaultCodePage;
847 else
848 pStream->nCodePage = RTFCharSetToCodePage(NULL, pStream->fonttbl[i].bCharSet);
849 }
850 }
851 }
852 if (*props)
853 strcat(props, " ");
854 if (!ME_StreamOutPrint(pStream, props))
855 return FALSE;
856 *old_fmt = *fmt;
857 return TRUE;
858}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define ARRAY_SIZE(A)
Definition: main.h:20
int RTFCharSetToCodePage(RTF_Info *info, int charset)
Definition: reader.c:476
static BOOL find_font_in_fonttbl(ME_OutStream *stream, CHARFORMAT2W *fmt, unsigned int *idx)
Definition: writer.c:255
static BOOL find_color_in_colortbl(ME_OutStream *stream, COLORREF color, unsigned int *idx)
Definition: writer.c:295
switch(r->id)
Definition: btrfs.c:3046
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define sprintf
Definition: sprintf.c:45
#define LOWORD(l)
Definition: pedump.c:82
#define CFU_UNDERLINEDOUBLE
Definition: richedit.h:430
#define CFE_SMALLCAPS
Definition: richedit.h:416
#define CFE_STRIKEOUT
Definition: richedit.h:409
#define CFE_OUTLINE
Definition: richedit.h:419
#define CFE_HIDDEN
Definition: richedit.h:418
#define CFE_BOLD
Definition: richedit.h:406
#define CFU_UNDERLINEWORD
Definition: richedit.h:429
#define CFE_ALLCAPS
Definition: richedit.h:417
#define CFE_ITALIC
Definition: richedit.h:407
#define CFE_DISABLED
Definition: richedit.h:423
#define CFE_SUPERSCRIPT
Definition: richedit.h:413
#define CFM_SUBSCRIPT
Definition: richedit.h:348
#define CFE_IMPRINT
Definition: richedit.h:422
#define CFE_UNDERLINE
Definition: richedit.h:408
#define CFE_SUBSCRIPT
Definition: richedit.h:412
#define CFE_PROTECTED
Definition: richedit.h:410
#define CFE_EMBOSS
Definition: richedit.h:421
#define CFU_CF1UNDERLINE
Definition: richedit.h:447
#define CFU_UNDERLINENONE
Definition: richedit.h:427
#define CFE_SHADOW
Definition: richedit.h:420
#define CFU_UNDERLINEDOTTED
Definition: richedit.h:431
#define CFM_SUPERSCRIPT
Definition: richedit.h:349
#define CP_UTF8
Definition: nls.h:20
strcat
Definition: string.h:92
BYTE bCharSet
Definition: richedit.h:311
WCHAR szFaceName[LF_FACESIZE]
Definition: richedit.h:313
BYTE bAnimation
Definition: richedit.h:322
WORD wKerning
Definition: richedit.h:320
LONG yOffset
Definition: richedit.h:309
SHORT sSpacing
Definition: richedit.h:315
LONG yHeight
Definition: richedit.h:308
COLORREF crBackColor
Definition: richedit.h:316
COLORREF crTextColor
Definition: richedit.h:310
ME_FontTableItem fonttbl[STREAMOUT_FONTTBL_SIZE]
Definition: writer.c:37
UINT nCodePage
Definition: writer.c:35
UINT nDefaultCodePage
Definition: writer.c:41
static const WCHAR props[]
Definition: wbemdisp.c:288

Referenced by ME_StreamOutRTF().

◆ ME_StreamOutRTFHeader()

static BOOL ME_StreamOutRTFHeader ( ME_OutStream pStream,
int  dwFormat 
)
static

Definition at line 163 of file writer.c.

164{
165 const char *cCharSet = NULL;
166 UINT nCodePage;
167 LANGID language;
169
170 if (dwFormat & SF_USECODEPAGE) {
172
173 switch (HIWORD(dwFormat)) {
174 case CP_ACP:
175 cCharSet = "ansi";
176 nCodePage = GetACP();
177 break;
178 case CP_OEMCP:
179 nCodePage = GetOEMCP();
180 if (nCodePage == 437)
181 cCharSet = "pc";
182 else if (nCodePage == 850)
183 cCharSet = "pca";
184 else
185 cCharSet = "ansi";
186 break;
187 case CP_UTF8:
188 nCodePage = CP_UTF8;
189 break;
190 default:
191 if (HIWORD(dwFormat) == CP_MACCP) {
192 cCharSet = "mac";
193 nCodePage = 10000; /* MacRoman */
194 } else {
195 cCharSet = "ansi";
196 nCodePage = 1252; /* Latin-1 */
197 }
198 if (GetCPInfoExW(HIWORD(dwFormat), 0, &info))
199 nCodePage = info.CodePage;
200 }
201 } else {
202 cCharSet = "ansi";
203 /* TODO: If the original document contained an \ansicpg value, retain it.
204 * Otherwise, M$ richedit emits a codepage number determined from the
205 * charset of the default font here. Anyway, this value is not used by
206 * the reader... */
207 nCodePage = GetACP();
208 }
209 if (nCodePage == CP_UTF8)
210 success = ME_StreamOutPrint(pStream, "{\\urtf");
211 else
212 success = ME_StreamOutPrint(pStream, "{\\rtf1\\%s\\ansicpg%u\\uc1", cCharSet, nCodePage);
213
214 if (!success)
215 return FALSE;
216
217 pStream->nDefaultCodePage = nCodePage;
218
219 /* FIXME: This should be a document property */
220 /* TODO: handle SFF_PLAINRTF */
221 language = GetUserDefaultLangID();
222 if (!ME_StreamOutPrint(pStream, "\\deff0\\deflang%u\\deflangfe%u", language, language))
223 return FALSE;
224
225 /* FIXME: This should be a document property */
226 pStream->nDefaultFont = 0;
227
228 return TRUE;
229}
#define CP_ACP
Definition: compat.h:109
UINT WINAPI GetACP(void)
Definition: locale.c:2023
BOOL WINAPI GetCPInfoExW(UINT codepage, DWORD dwFlags, LPCPINFOEXW cpinfo)
Definition: locale.c:2222
LANGID WINAPI GetUserDefaultLangID(void)
Definition: locale.c:1182
UINT WINAPI GetOEMCP(void)
Definition: locale.c:2062
unsigned int BOOL
Definition: ntddk_ex.h:94
USHORT LANGID
Definition: mui.h:9
#define SF_USECODEPAGE
Definition: richedit.h:725
UINT nDefaultFont
Definition: writer.c:40
#define HIWORD(l)
Definition: typedefs.h:247
#define success(from, fromstr, to, tostr)
#define CP_OEMCP
Definition: winnls.h:249
#define CP_MACCP
Definition: winnls.h:250

Referenced by ME_StreamOutRTF().

◆ ME_StreamOutRTFText()

static BOOL ME_StreamOutRTFText ( ME_OutStream pStream,
const WCHAR text,
LONG  nChars 
)
static

Definition at line 862 of file writer.c.

863{
865 int pos = 0;
866 int fit, nBytes, i;
867
868 if (nChars == -1)
869 nChars = lstrlenW(text);
870
871 while (nChars) {
872 /* In UTF-8 mode, font charsets are not used. */
873 if (pStream->nDefaultCodePage == CP_UTF8) {
874 /* 6 is the maximum character length in UTF-8 */
875 fit = min(nChars, STREAMOUT_BUFFER_SIZE / 6);
876 nBytes = WideCharToMultiByte(CP_UTF8, 0, text, fit, buffer,
878 nChars -= fit;
879 text += fit;
880 for (i = 0; i < nBytes; i++)
881 if (buffer[i] == '{' || buffer[i] == '}' || buffer[i] == '\\') {
882 if (!ME_StreamOutPrint(pStream, "%.*s\\", i - pos, buffer + pos))
883 return FALSE;
884 pos = i;
885 }
886 if (pos < nBytes)
887 if (!ME_StreamOutMove(pStream, buffer + pos, nBytes - pos))
888 return FALSE;
889 pos = 0;
890 } else if (*text < 128) {
891 if (*text == '{' || *text == '}' || *text == '\\')
892 buffer[pos++] = '\\';
893 buffer[pos++] = (char)(*text++);
894 nChars--;
895 } else {
897 char letter[3];
898
899 /* FIXME: In the MS docs for WideCharToMultiByte there is a big list of
900 * codepages including CP_SYMBOL for which the last parameter must be set
901 * to NULL for the function to succeed. But in Wine we need to care only
902 * about CP_SYMBOL */
903 nBytes = WideCharToMultiByte(pStream->nCodePage, 0, text, 1,
904 letter, 3, NULL,
905 (pStream->nCodePage == CP_SYMBOL) ? NULL : &unknown);
906 if (unknown)
907 pos += sprintf(buffer + pos, "\\u%d?", (short)*text);
908 else if ((BYTE)*letter < 128) {
909 if (*letter == '{' || *letter == '}' || *letter == '\\')
910 buffer[pos++] = '\\';
911 buffer[pos++] = *letter;
912 } else {
913 for (i = 0; i < nBytes; i++)
914 pos += sprintf(buffer + pos, "\\'%02x", (BYTE)letter[i]);
915 }
916 text++;
917 nChars--;
918 }
919 if (pos >= STREAMOUT_BUFFER_SIZE - 11) {
920 if (!ME_StreamOutMove(pStream, buffer, pos))
921 return FALSE;
922 pos = 0;
923 }
924 }
925 return ME_StreamOutMove(pStream, buffer, pos);
926}
static WCHAR unknown[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1605
#define WideCharToMultiByte
Definition: compat.h:111
#define lstrlenW
Definition: compat.h:750
const WCHAR * text
Definition: package.c:1794
unsigned char
Definition: typeof.h:29
#define CP_SYMBOL
Definition: winnls.h:252

Referenced by ME_StreamOutRTF(), stream_out_font_and_colour_tbls(), and stream_out_para_num().

◆ ME_StreamOutText()

static BOOL ME_StreamOutText ( ME_TextEditor editor,
ME_OutStream pStream,
const ME_Cursor start,
int  nChars,
DWORD  dwFormat 
)
static

Definition at line 1119 of file writer.c.

1121{
1123 int nLen;
1124 UINT nCodePage = CP_ACP;
1125 char *buffer = NULL;
1126 int nBufLen = 0;
1127 BOOL success = TRUE;
1128
1129 if (!cursor.run)
1130 return FALSE;
1131
1132 if (dwFormat & SF_USECODEPAGE)
1133 nCodePage = HIWORD(dwFormat);
1134
1135 /* TODO: Handle SF_TEXTIZED */
1136
1137 while (success && nChars && cursor.run)
1138 {
1139 nLen = min(nChars, cursor.run->len - cursor.nOffset);
1140
1141 if (!editor->bEmulateVersion10 && cursor.run->nFlags & MERF_ENDPARA)
1142 {
1143 /* richedit 2.0 - all line breaks are \r\n */
1144 if (dwFormat & SF_UNICODE)
1145 success = ME_StreamOutMove(pStream, (const char *)L"\r\n", 2 * sizeof(WCHAR));
1146 else
1147 success = ME_StreamOutMove(pStream, "\r\n", 2);
1148 } else {
1149 if (dwFormat & SF_UNICODE)
1150 success = ME_StreamOutMove(pStream, (const char *)(get_text( cursor.run, cursor.nOffset )),
1151 sizeof(WCHAR) * nLen);
1152 else {
1153 int nSize;
1154
1155 nSize = WideCharToMultiByte(nCodePage, 0, get_text( cursor.run, cursor.nOffset ),
1156 nLen, NULL, 0, NULL, NULL);
1157 if (nSize > nBufLen) {
1159 nBufLen = nSize;
1160 }
1161 WideCharToMultiByte(nCodePage, 0, get_text( cursor.run, cursor.nOffset ),
1162 nLen, buffer, nSize, NULL, NULL);
1163 success = ME_StreamOutMove(pStream, buffer, nSize);
1164 }
1165 }
1166
1167 nChars -= nLen;
1168 cursor.nOffset = 0;
1169 cursor.run = run_next_all_paras( cursor.run );
1170 }
1171
1172 free(buffer);
1173 return success;
1174}
#define realloc
Definition: debug_ros.c:6
#define L(x)
Definition: resources.c:13
ME_Run * run_next_all_paras(ME_Run *run)
Definition: run.c:96
#define SF_UNICODE
Definition: richedit.h:724
*nSize LPSTR _Inout_ LPDWORD nSize
Definition: winbase.h:1834

Referenced by ME_StreamOutRange().

◆ stream_out_font_and_colour_tbls()

static BOOL stream_out_font_and_colour_tbls ( ME_OutStream pStream,
ME_Run first,
ME_Run last 
)
static

Definition at line 312 of file writer.c.

313{
314 ME_Run *run = first;
315 ME_FontTableItem *table = pStream->fonttbl;
316 unsigned int i;
317 ME_Cell *cell = NULL;
318 ME_Paragraph *prev_para = NULL;
319
320 do
321 {
322 CHARFORMAT2W *fmt = &run->style->fmt;
323
324 add_font_to_fonttbl( pStream, run->style );
325
326 if (fmt->dwMask & CFM_COLOR && !(fmt->dwEffects & CFE_AUTOCOLOR))
327 add_color_to_colortbl( pStream, fmt->crTextColor );
328 if (fmt->dwMask & CFM_BACKCOLOR && !(fmt->dwEffects & CFE_AUTOBACKCOLOR))
329 add_color_to_colortbl( pStream, fmt->crBackColor );
330
331 if (run->para != prev_para)
332 {
333 /* check for any para numbering text */
334 if (run->para->fmt.wNumbering)
335 add_font_to_fonttbl( pStream, run->para->para_num.style );
336
337 if ((cell = para_cell( run->para )))
338 {
339 ME_Border* borders[4] = { &cell->border.top, &cell->border.left,
340 &cell->border.bottom, &cell->border.right };
341 for (i = 0; i < 4; i++)
342 if (borders[i]->width > 0)
343 add_color_to_colortbl( pStream, borders[i]->colorRef );
344 }
345
346 prev_para = run->para;
347 }
348
349 if (run == last) break;
350 run = run_next_all_paras( run );
351 } while (run);
352
353 if (!ME_StreamOutPrint(pStream, "{\\fonttbl"))
354 return FALSE;
355
356 for (i = 0; i < pStream->nFontTblLen; i++) {
357 if (table[i].bCharSet != DEFAULT_CHARSET) {
358 if (!ME_StreamOutPrint(pStream, "{\\f%u\\fcharset%u ", i, table[i].bCharSet))
359 return FALSE;
360 } else {
361 if (!ME_StreamOutPrint(pStream, "{\\f%u ", i))
362 return FALSE;
363 }
364 if (!ME_StreamOutRTFText(pStream, table[i].szFaceName, -1))
365 return FALSE;
366 if (!ME_StreamOutPrint(pStream, ";}"))
367 return FALSE;
368 }
369 if (!ME_StreamOutPrint(pStream, "}\r\n"))
370 return FALSE;
371
372 /* Output the color table */
373 if (!ME_StreamOutPrint(pStream, "{\\colortbl;")) return FALSE; /* first entry is auto-color */
374 for (i = 1; i < pStream->nColorTblLen; i++)
375 {
376 if (!ME_StreamOutPrint(pStream, "\\red%u\\green%u\\blue%u;", pStream->colortbl[i] & 0xFF,
377 (pStream->colortbl[i] >> 8) & 0xFF, (pStream->colortbl[i] >> 16) & 0xFF))
378 return FALSE;
379 }
380 if (!ME_StreamOutPrint(pStream, "}\r\n")) return FALSE;
381
382 return TRUE;
383}
static void add_color_to_colortbl(ME_OutStream *stream, COLORREF color)
Definition: writer.c:280
static void add_font_to_fonttbl(ME_OutStream *stream, ME_Style *style)
Definition: writer.c:231
ME_Cell * para_cell(ME_Paragraph *para)
Definition: para.c:127
GLint GLint GLsizei width
Definition: gl.h:1546
const GLint * first
Definition: glext.h:5794
static UINT UINT last
Definition: font.c:45
#define CFM_BACKCOLOR
Definition: richedit.h:357
#define CFM_COLOR
Definition: richedit.h:361
ME_Border bottom
Definition: editstr.h:190
ME_Border right
Definition: editstr.h:191
ME_Border left
Definition: editstr.h:189
ME_Border top
Definition: editstr.h:188
ME_BorderRect border
Definition: editstr.h:225
COLORREF colortbl[STREAMOUT_COLORTBL_SIZE]
Definition: writer.c:39
UINT nFontTblLen
Definition: writer.c:36
struct tagME_Paragraph * para
Definition: editstr.h:161
ME_Style * style
Definition: editstr.h:160
CHARFORMAT2W fmt
Definition: editstr.h:71

Referenced by ME_StreamOutRTF().

◆ stream_out_graphics()

static BOOL stream_out_graphics ( ME_TextEditor editor,
ME_OutStream stream,
ME_Run run 
)
static

Definition at line 928 of file writer.c.

930{
932 HRESULT hr;
933 FORMATETC fmt = { CF_ENHMETAFILE, NULL, DVASPECT_CONTENT, -1, TYMED_ENHMF };
934 STGMEDIUM med = { TYMED_NULL };
935 BOOL ret = FALSE;
936 ENHMETAHEADER *emf_bits = NULL;
937 UINT size;
938 SIZE goal, pic;
940 HDC hdc;
941
942 hr = IOleObject_QueryInterface( run->reobj->obj.poleobj, &IID_IDataObject, (void **)&data );
943 if (FAILED(hr)) return FALSE;
944
945 hdc = ITextHost_TxGetDC( editor->texthost );
946 ME_InitContext( &c, editor, hdc );
947 hr = IDataObject_QueryGetData( data, &fmt );
948 if (hr != S_OK) goto done;
949
950 hr = IDataObject_GetData( data, &fmt, &med );
951 if (FAILED(hr)) goto done;
952 if (med.tymed != TYMED_ENHMF) goto done;
953
954 size = GetEnhMetaFileBits( med.hEnhMetaFile, 0, NULL );
955 if (size < FIELD_OFFSET(ENHMETAHEADER, cbPixelFormat)) goto done;
956
957 emf_bits = malloc( size );
958 if (!emf_bits) goto done;
959
960 size = GetEnhMetaFileBits( med.hEnhMetaFile, size, (BYTE *)emf_bits );
961 if (size < FIELD_OFFSET(ENHMETAHEADER, cbPixelFormat)) goto done;
962
963 /* size_in_pixels = (frame_size / 100) * szlDevice / szlMillimeters
964 pic = size_in_pixels * 2540 / dpi */
965 pic.cx = MulDiv( emf_bits->rclFrame.right - emf_bits->rclFrame.left, emf_bits->szlDevice.cx * 254,
966 emf_bits->szlMillimeters.cx * c.dpi.cx * 10 );
967 pic.cy = MulDiv( emf_bits->rclFrame.bottom - emf_bits->rclFrame.top, emf_bits->szlDevice.cy * 254,
968 emf_bits->szlMillimeters.cy * c.dpi.cy * 10 );
969
970 /* convert goal size to twips */
971 goal.cx = MulDiv( run->reobj->obj.sizel.cx, 144, 254 );
972 goal.cy = MulDiv( run->reobj->obj.sizel.cy, 144, 254 );
973
974 if (!ME_StreamOutPrint( stream, "{\\*\\shppict{\\pict\\emfblip\\picw%d\\pich%d\\picwgoal%d\\pichgoal%d\n",
975 pic.cx, pic.cy, goal.cx, goal.cy ))
976 goto done;
977
978 if (!ME_StreamOutHexData( stream, (BYTE *)emf_bits, size ))
979 goto done;
980
981 if (!ME_StreamOutPrint( stream, "}}\n" ))
982 goto done;
983
984 ret = TRUE;
985
986done:
989 free( emf_bits );
990 ReleaseStgMedium( &med );
991 IDataObject_Release( data );
992 return ret;
993}
#define CF_ENHMETAFILE
Definition: constants.h:409
#define malloc
Definition: debug_ros.c:4
void WINAPI ReleaseStgMedium(STGMEDIUM *pmedium)
Definition: ole2.c:2033
void ME_DestroyContext(ME_Context *c)
Definition: context.c:44
void ME_InitContext(ME_Context *c, ME_TextEditor *editor, HDC hDC)
Definition: context.c:23
static BOOL ME_StreamOutHexData(ME_OutStream *stream, const BYTE *data, UINT len)
Definition: writer.c:138
return ret
Definition: mutex.c:146
#define ITextHost_TxGetDC(This)
Definition: editor.h:332
#define ITextHost_TxReleaseDC(This, a)
Definition: editor.h:333
const GLubyte * c
Definition: glext.h:8905
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
#define c
Definition: ke_i.h:80
HDC hdc
Definition: main.c:9
static HDC
Definition: imagelist.c:88
INT WINAPI MulDiv(INT nNumber, INT nNumerator, INT nDenominator)
Definition: muldiv.c:25
const GUID IID_IDataObject
HRESULT hr
Definition: shlfolder.c:183
long bottom
Definition: polytest.cpp:53
long right
Definition: polytest.cpp:53
long top
Definition: polytest.cpp:53
long left
Definition: polytest.cpp:53
LONG cx
Definition: kdterminal.h:27
LONG cy
Definition: kdterminal.h:28
RECTL rclFrame
Definition: wingdi.h:2769
SIZEL szlDevice
Definition: wingdi.h:2779
SIZEL szlMillimeters
Definition: wingdi.h:2780
struct re_object * reobj
Definition: editstr.h:168
ITextHost2 * texthost
Definition: editstr.h:391
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
UINT WINAPI GetEnhMetaFileBits(_In_ HENHMETAFILE hEMF, _In_ UINT nSize, _Out_writes_bytes_opt_(nSize) LPBYTE lpData)

Referenced by ME_StreamOutRTF().

◆ stream_out_para_num()

static BOOL stream_out_para_num ( ME_OutStream stream,
ME_Paragraph para,
BOOL  pn_dest 
)
static

Definition at line 462 of file writer.c.

463{
464 static const char fmt_label[] = "{\\*\\pn\\pnlvlbody\\pnf%u\\pnindent%d\\pnstart%d%s%s}";
465 static const char fmt_bullet[] = "{\\*\\pn\\pnlvlblt\\pnf%u\\pnindent%d{\\pntxtb\\'b7}}";
466 static const char dec[] = "\\pndec";
467 static const char lcltr[] = "\\pnlcltr";
468 static const char ucltr[] = "\\pnucltr";
469 static const char lcrm[] = "\\pnlcrm";
470 static const char ucrm[] = "\\pnucrm";
471 static const char period[] = "{\\pntxta.}";
472 static const char paren[] = "{\\pntxta)}";
473 static const char parens[] = "{\\pntxtb(}{\\pntxta)}";
474 const char *type, *style = "";
475 unsigned int idx;
476
477 find_font_in_fonttbl( stream, &para->para_num.style->fmt, &idx );
478
479 if (!ME_StreamOutPrint( stream, "{\\pntext\\f%u ", idx )) return FALSE;
480 if (!ME_StreamOutRTFText( stream, para->para_num.text->szData, para->para_num.text->nLen ))
481 return FALSE;
482 if (!ME_StreamOutPrint( stream, "\\tab}" )) return FALSE;
483
484 if (!pn_dest) return TRUE;
485
486 if (para->fmt.wNumbering == PFN_BULLET)
487 {
488 if (!ME_StreamOutPrint( stream, fmt_bullet, idx, para->fmt.wNumberingTab ))
489 return FALSE;
490 }
491 else
492 {
493 switch (para->fmt.wNumbering)
494 {
495 case PFN_ARABIC:
496 default:
497 type = dec;
498 break;
499 case PFN_LCLETTER:
500 type = lcltr;
501 break;
502 case PFN_UCLETTER:
503 type = ucltr;
504 break;
505 case PFN_LCROMAN:
506 type = lcrm;
507 break;
508 case PFN_UCROMAN:
509 type = ucrm;
510 break;
511 }
512 switch (para->fmt.wNumberingStyle & 0xf00)
513 {
514 case PFNS_PERIOD:
515 style = period;
516 break;
517 case PFNS_PAREN:
518 style = paren;
519 break;
520 case PFNS_PARENS:
521 style = parens;
522 break;
523 }
524
525 if (!ME_StreamOutPrint( stream, fmt_label, idx, para->fmt.wNumberingTab,
526 para->fmt.wNumberingStart, type, style ))
527 return FALSE;
528 }
529 return TRUE;
530}
ios_base &_STLP_CALL dec(ios_base &__s)
Definition: _ios_base.h:321
#define PFN_UCLETTER
Definition: richedit.h:908
#define PFN_ARABIC
Definition: richedit.h:906
#define PFN_LCLETTER
Definition: richedit.h:907
#define PFN_UCROMAN
Definition: richedit.h:910
#define PFNS_PAREN
Definition: richedit.h:913
#define PFN_BULLET
Definition: richedit.h:905
#define PFN_LCROMAN
Definition: richedit.h:909
#define PFNS_PARENS
Definition: richedit.h:914
#define PFNS_PERIOD
Definition: richedit.h:915
WORD wNumberingStart
Definition: richedit.h:680
WORD wNumberingStyle
Definition: richedit.h:680
WORD wNumbering
Definition: richedit.h:668
WORD wNumberingTab
Definition: richedit.h:680
struct para_num para_num
Definition: editstr.h:215
PARAFORMAT2 fmt
Definition: editstr.h:204

Referenced by stream_out_para_props().

◆ stream_out_para_props()

static BOOL stream_out_para_props ( ME_TextEditor editor,
ME_OutStream pStream,
ME_Paragraph para 
)
static

Definition at line 532 of file writer.c.

534{
535 PARAFORMAT2 *fmt = &para->fmt;
536 char props[STREAMOUT_BUFFER_SIZE] = "";
537 int i;
538 ME_Paragraph *prev_para = para_prev( para );
539
540 if (!editor->bEmulateVersion10) /* v4.1 */
541 {
542 if (para->nFlags & MEPF_ROWSTART)
543 {
544 pStream->nNestingLevel++;
545 if (pStream->nNestingLevel == 1)
546 if (!stream_out_table_props( editor, pStream, para )) return FALSE;
547 return TRUE;
548 }
549 else if (para->nFlags & MEPF_ROWEND)
550 {
551 pStream->nNestingLevel--;
552 if (pStream->nNestingLevel >= 1)
553 {
554 if (!ME_StreamOutPrint(pStream, "{\\*\\nesttableprops")) return FALSE;
555 if (!stream_out_table_props( editor, pStream, para )) return FALSE;
556 if (!ME_StreamOutPrint(pStream, "\\nestrow}{\\nonesttables\\par}\r\n")) return FALSE;
557 }
558 else if (!ME_StreamOutPrint(pStream, "\\row\r\n")) return FALSE;
559 return TRUE;
560 }
561 }
562 else /* v1.0 - 3.0 */
563 {
564 if (para->fmt.dwMask & PFM_TABLE && para->fmt.wEffects & PFE_TABLE)
565 if (!stream_out_table_props( editor, pStream, para )) return FALSE;
566 }
567
568 if (prev_para && !memcmp( fmt, &prev_para->fmt, sizeof(*fmt) ))
569 {
570 if (fmt->wNumbering)
571 return stream_out_para_num( pStream, para, FALSE );
572 return TRUE;
573 }
574
575 if (!ME_StreamOutPrint(pStream, "\\pard"))
576 return FALSE;
577
578 if (fmt->wNumbering)
579 if (!stream_out_para_num( pStream, para, TRUE )) return FALSE;
580
581 if (!editor->bEmulateVersion10) /* v4.1 */
582 {
583 if (pStream->nNestingLevel > 0) strcat(props, "\\intbl");
584 if (pStream->nNestingLevel > 1) sprintf(props + strlen(props), "\\itap%d", pStream->nNestingLevel);
585 }
586 else /* v1.0 - 3.0 */
587 {
588 if (fmt->dwMask & PFM_TABLE && fmt->wEffects & PFE_TABLE)
589 strcat(props, "\\intbl");
590 }
591
592 /* TODO: PFM_BORDER. M$ does not emit any keywords for these properties, and
593 * when streaming border keywords in, PFM_BORDER is set, but wBorder field is
594 * set very different from the documentation.
595 * (Tested with RichEdit 5.50.25.0601) */
596
597 if (fmt->dwMask & PFM_ALIGNMENT)
598 {
599 switch (fmt->wAlignment)
600 {
601 case PFA_LEFT:
602 /* Default alignment: not emitted */
603 break;
604 case PFA_RIGHT:
605 strcat(props, "\\qr");
606 break;
607 case PFA_CENTER:
608 strcat(props, "\\qc");
609 break;
610 case PFA_JUSTIFY:
611 strcat(props, "\\qj");
612 break;
613 }
614 }
615
616 if (fmt->dwMask & PFM_LINESPACING)
617 {
618 /* FIXME: MSDN says that the bLineSpacingRule field is controlled by the
619 * PFM_SPACEAFTER flag. Is that true? I don't believe so. */
620 switch (fmt->bLineSpacingRule)
621 {
622 case 0: /* Single spacing */
623 strcat(props, "\\sl-240\\slmult1");
624 break;
625 case 1: /* 1.5 spacing */
626 strcat(props, "\\sl-360\\slmult1");
627 break;
628 case 2: /* Double spacing */
629 strcat(props, "\\sl-480\\slmult1");
630 break;
631 case 3:
632 sprintf(props + strlen(props), "\\sl%ld\\slmult0", fmt->dyLineSpacing);
633 break;
634 case 4:
635 sprintf(props + strlen(props), "\\sl-%ld\\slmult0", fmt->dyLineSpacing);
636 break;
637 case 5:
638 sprintf(props + strlen(props), "\\sl-%ld\\slmult1", fmt->dyLineSpacing * 240 / 20);
639 break;
640 }
641 }
642
643 if (fmt->dwMask & PFM_DONOTHYPHEN && fmt->wEffects & PFE_DONOTHYPHEN)
644 strcat(props, "\\hyph0");
645 if (fmt->dwMask & PFM_KEEP && fmt->wEffects & PFE_KEEP)
646 strcat(props, "\\keep");
647 if (fmt->dwMask & PFM_KEEPNEXT && fmt->wEffects & PFE_KEEPNEXT)
648 strcat(props, "\\keepn");
649 if (fmt->dwMask & PFM_NOLINENUMBER && fmt->wEffects & PFE_NOLINENUMBER)
650 strcat(props, "\\noline");
651 if (fmt->dwMask & PFM_NOWIDOWCONTROL && fmt->wEffects & PFE_NOWIDOWCONTROL)
652 strcat(props, "\\nowidctlpar");
653 if (fmt->dwMask & PFM_PAGEBREAKBEFORE && fmt->wEffects & PFE_PAGEBREAKBEFORE)
654 strcat(props, "\\pagebb");
655 if (fmt->dwMask & PFM_RTLPARA && fmt->wEffects & PFE_RTLPARA)
656 strcat(props, "\\rtlpar");
657 if (fmt->dwMask & PFM_SIDEBYSIDE && fmt->wEffects & PFE_SIDEBYSIDE)
658 strcat(props, "\\sbys");
659
660 if (!(editor->bEmulateVersion10 && /* v1.0 - 3.0 */
661 fmt->dwMask & PFM_TABLE && fmt->wEffects & PFE_TABLE))
662 {
663 if (fmt->dxOffset)
664 sprintf(props + strlen(props), "\\li%ld", fmt->dxOffset);
665 if (fmt->dxStartIndent)
666 sprintf(props + strlen(props), "\\fi%ld", fmt->dxStartIndent);
667 if (fmt->dxRightIndent)
668 sprintf(props + strlen(props), "\\ri%ld", fmt->dxRightIndent);
669 if (fmt->dwMask & PFM_TABSTOPS) {
670 static const char * const leader[6] = { "", "\\tldot", "\\tlhyph", "\\tlul", "\\tlth", "\\tleq" };
671
672 for (i = 0; i < fmt->cTabCount; i++)
673 {
674 switch ((fmt->rgxTabs[i] >> 24) & 0xf)
675 {
676 case 1:
677 strcat(props, "\\tqc");
678 break;
679 case 2:
680 strcat(props, "\\tqr");
681 break;
682 case 3:
683 strcat(props, "\\tqdec");
684 break;
685 case 4:
686 /* Word bar tab (vertical bar). Handled below */
687 break;
688 }
689 if (fmt->rgxTabs[i] >> 28 <= 5)
690 strcat(props, leader[fmt->rgxTabs[i] >> 28]);
691 sprintf(props+strlen(props), "\\tx%ld", fmt->rgxTabs[i]&0x00FFFFFF);
692 }
693 }
694 }
695 if (fmt->dySpaceAfter)
696 sprintf(props + strlen(props), "\\sa%ld", fmt->dySpaceAfter);
697 if (fmt->dySpaceBefore)
698 sprintf(props + strlen(props), "\\sb%ld", fmt->dySpaceBefore);
699 if (fmt->sStyle != -1)
700 sprintf(props + strlen(props), "\\s%d", fmt->sStyle);
701
702 if (fmt->dwMask & PFM_SHADING)
703 {
704 static const char * const style[16] = { "", "\\bgdkhoriz", "\\bgdkvert", "\\bgdkfdiag",
705 "\\bgdkbdiag", "\\bgdkcross", "\\bgdkdcross",
706 "\\bghoriz", "\\bgvert", "\\bgfdiag",
707 "\\bgbdiag", "\\bgcross", "\\bgdcross",
708 "", "", "" };
709 if (fmt->wShadingWeight)
710 sprintf(props + strlen(props), "\\shading%d", fmt->wShadingWeight);
711 if (fmt->wShadingStyle & 0xF)
712 strcat(props, style[fmt->wShadingStyle & 0xF]);
713 if ((fmt->wShadingStyle >> 4) & 0xf)
714 sprintf(props + strlen(props), "\\cfpat%d", (fmt->wShadingStyle >> 4) & 0xf);
715 if ((fmt->wShadingStyle >> 8) & 0xf)
716 sprintf(props + strlen(props), "\\cbpat%d", (fmt->wShadingStyle >> 8) & 0xf);
717 }
718 if (*props)
719 strcat(props, " ");
720
721 if (*props && !ME_StreamOutPrint(pStream, props))
722 return FALSE;
723
724 return TRUE;
725}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
static BOOL stream_out_table_props(ME_TextEditor *editor, ME_OutStream *pStream, ME_Paragraph *para)
Definition: writer.c:385
static BOOL stream_out_para_num(ME_OutStream *stream, ME_Paragraph *para, BOOL pn_dest)
Definition: writer.c:462
ME_Paragraph * para_prev(ME_Paragraph *para)
Definition: para.c:63
#define PFA_RIGHT
Definition: richedit.h:922
#define PFA_CENTER
Definition: richedit.h:923
#define PFE_RTLPARA
Definition: richedit.h:932
#define PFE_KEEP
Definition: richedit.h:933
#define PFE_DONOTHYPHEN
Definition: richedit.h:938
#define PFE_NOWIDOWCONTROL
Definition: richedit.h:937
#define PFA_LEFT
Definition: richedit.h:921
#define PFM_NOLINENUMBER
Definition: richedit.h:860
#define PFM_KEEPNEXT
Definition: richedit.h:858
#define PFM_DONOTHYPHEN
Definition: richedit.h:862
#define PFM_LINESPACING
Definition: richedit.h:849
#define PFM_SHADING
Definition: richedit.h:852
#define PFM_TABLE
Definition: richedit.h:870
#define PFE_SIDEBYSIDE
Definition: richedit.h:939
#define PFM_NOWIDOWCONTROL
Definition: richedit.h:861
#define PFE_NOLINENUMBER
Definition: richedit.h:936
#define PFM_PAGEBREAKBEFORE
Definition: richedit.h:859
#define PFE_TABLE
Definition: richedit.h:944
#define PFE_PAGEBREAKBEFORE
Definition: richedit.h:935
#define PFM_ALIGNMENT
Definition: richedit.h:841
#define PFM_SIDEBYSIDE
Definition: richedit.h:863
#define PFA_JUSTIFY
Definition: richedit.h:924
#define PFM_TABSTOPS
Definition: richedit.h:842
#define PFM_KEEP
Definition: richedit.h:857
#define PFM_RTLPARA
Definition: richedit.h:856
#define PFE_KEEPNEXT
Definition: richedit.h:934
DWORD dwMask
Definition: richedit.h:667
WORD wEffects
Definition: richedit.h:669

Referenced by ME_StreamOutRTF().

◆ stream_out_table_props()

static BOOL stream_out_table_props ( ME_TextEditor editor,
ME_OutStream pStream,
ME_Paragraph para 
)
static

Definition at line 385 of file writer.c.

387{
388 ME_Cell *cell;
389 char props[STREAMOUT_BUFFER_SIZE] = "";
390 int i;
391 const char sideChar[4] = {'t','l','b','r'};
392
393 if (!ME_StreamOutPrint(pStream, "\\trowd"))
394 return FALSE;
395 if (!editor->bEmulateVersion10) /* v4.1 */
396 {
397 PARAFORMAT2 *pFmt = &table_row_end( para )->fmt;
398 cell = table_row_first_cell( para );
399 assert( cell );
400 if (pFmt->dxOffset)
401 sprintf(props + strlen(props), "\\trgaph%ld", pFmt->dxOffset);
402 if (pFmt->dxStartIndent)
403 sprintf(props + strlen(props), "\\trleft%ld", pFmt->dxStartIndent);
404 do
405 {
406 ME_Border* borders[4] = { &cell->border.top, &cell->border.left,
407 &cell->border.bottom, &cell->border.right };
408 for (i = 0; i < 4; i++)
409 {
410 if (borders[i]->width)
411 {
412 unsigned int idx;
413 COLORREF crColor = borders[i]->colorRef;
414 sprintf(props + strlen(props), "\\clbrdr%c", sideChar[i]);
415 sprintf(props + strlen(props), "\\brdrs");
416 sprintf(props + strlen(props), "\\brdrw%d", borders[i]->width);
417 if (find_color_in_colortbl( pStream, crColor, &idx ))
418 sprintf(props + strlen(props), "\\brdrcf%u", idx);
419 }
420 }
421 sprintf( props + strlen(props), "\\cellx%d", cell->nRightBoundary );
422 cell = cell_next( cell );
423 } while (cell_next( cell ));
424 }
425 else /* v1.0 - 3.0 */
426 {
427 const ME_Border* borders[4] = { &para->border.top,
428 &para->border.left,
429 &para->border.bottom,
430 &para->border.right };
431 PARAFORMAT2 *pFmt = &para->fmt;
432
433 assert( !(para->nFlags & (MEPF_ROWSTART | MEPF_ROWEND | MEPF_CELL)) );
434 if (pFmt->dxOffset)
435 sprintf(props + strlen(props), "\\trgaph%ld", pFmt->dxOffset);
436 if (pFmt->dxStartIndent)
437 sprintf(props + strlen(props), "\\trleft%ld", pFmt->dxStartIndent);
438 for (i = 0; i < 4; i++)
439 {
440 if (borders[i]->width)
441 {
442 unsigned int idx;
443 COLORREF crColor = borders[i]->colorRef;
444 sprintf(props + strlen(props), "\\trbrdr%c", sideChar[i]);
445 sprintf(props + strlen(props), "\\brdrs");
446 sprintf(props + strlen(props), "\\brdrw%d", borders[i]->width);
447 if (find_color_in_colortbl( pStream, crColor, &idx ))
448 sprintf(props + strlen(props), "\\brdrcf%u", idx);
449 }
450 }
451 for (i = 0; i < pFmt->cTabCount; i++)
452 {
453 sprintf(props + strlen(props), "\\cellx%ld", pFmt->rgxTabs[i] & 0x00FFFFFF);
454 }
455 }
456 if (!ME_StreamOutPrint(pStream, props))
457 return FALSE;
458 props[0] = '\0';
459 return TRUE;
460}
#define assert(x)
Definition: debug.h:53
ME_Cell * cell_next(ME_Cell *cell)
Definition: table.c:192
ME_Cell * table_row_first_cell(ME_Paragraph *para)
Definition: table.c:170
ME_Paragraph * table_row_end(ME_Paragraph *para)
Definition: table.c:127
LONG dxOffset
Definition: richedit.h:672
LONG rgxTabs[MAX_TAB_STOPS]
Definition: richedit.h:675
SHORT cTabCount
Definition: richedit.h:674
LONG dxStartIndent
Definition: richedit.h:670
COLORREF colorRef
Definition: editstr.h:183
int nRightBoundary
Definition: editstr.h:224
ME_BorderRect border
Definition: editstr.h:208
DWORD COLORREF
Definition: windef.h:94

Referenced by stream_out_para_props().

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( richedit  )