ReactOS 0.4.17-dev-470-gf9e3448
writer.c
Go to the documentation of this file.
1/*
2 * RichEdit - RTF writer module
3 *
4 * Copyright 2005 by Phil Krylov
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 */
20
21#include "editor.h"
22#include "rtf.h"
23
25
26#define STREAMOUT_BUFFER_SIZE 4096
27#define STREAMOUT_FONTTBL_SIZE 8192
28#define STREAMOUT_COLORTBL_SIZE 1024
29
30typedef struct tagME_OutStream
31{
42 /* nNestingLevel = 0 means we aren't in a cell, 1 means we are in a cell,
43 * an greater numbers mean we are in a cell nested within a cell. */
45 CHARFORMAT2W cur_fmt; /* current character format */
47
48static BOOL
49ME_StreamOutRTFText(ME_OutStream *pStream, const WCHAR *text, LONG nChars);
50
51
52static ME_OutStream*
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}
64
65
66static BOOL
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}
87
88
89static LONG
91{
92 LONG written = pStream->written;
93 TRACE("total length = %lu\n", written);
94
95 free(pStream);
96 return written;
97}
98
99
100static BOOL
101ME_StreamOutMove(ME_OutStream *pStream, const char *buffer, int len)
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}
119
120
121static BOOL WINAPIV
122ME_StreamOutPrint(ME_OutStream *pStream, const char *format, ...)
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}
134
135#define HEX_BYTES_PER_LINE 40
136
137static BOOL
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}
161
162static BOOL
163ME_StreamOutRTFHeader(ME_OutStream *pStream, int dwFormat)
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}
230
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}
254
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}
279
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}
294
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}
311
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}
384
386 ME_Paragraph *para )
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}
461
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}
531
533 ME_Paragraph *para )
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#ifdef __REACTOS__ /* Import fix from Wine-11.3 */
690 if ((ULONG)fmt->rgxTabs[i] >> 28 <= 5)
691 strcat(props, leader[(ULONG)fmt->rgxTabs[i] >> 28]);
692#else
693 if (fmt->rgxTabs[i] >> 28 <= 5)
694 strcat(props, leader[fmt->rgxTabs[i] >> 28]);
695#endif
696 sprintf(props+strlen(props), "\\tx%ld", fmt->rgxTabs[i]&0x00FFFFFF);
697 }
698 }
699 }
700 if (fmt->dySpaceAfter)
701 sprintf(props + strlen(props), "\\sa%ld", fmt->dySpaceAfter);
702 if (fmt->dySpaceBefore)
703 sprintf(props + strlen(props), "\\sb%ld", fmt->dySpaceBefore);
704 if (fmt->sStyle != -1)
705 sprintf(props + strlen(props), "\\s%d", fmt->sStyle);
706
707 if (fmt->dwMask & PFM_SHADING)
708 {
709 static const char * const style[16] = { "", "\\bgdkhoriz", "\\bgdkvert", "\\bgdkfdiag",
710 "\\bgdkbdiag", "\\bgdkcross", "\\bgdkdcross",
711 "\\bghoriz", "\\bgvert", "\\bgfdiag",
712 "\\bgbdiag", "\\bgcross", "\\bgdcross",
713 "", "", "" };
714 if (fmt->wShadingWeight)
715 sprintf(props + strlen(props), "\\shading%d", fmt->wShadingWeight);
716 if (fmt->wShadingStyle & 0xF)
717 strcat(props, style[fmt->wShadingStyle & 0xF]);
718 if ((fmt->wShadingStyle >> 4) & 0xf)
719 sprintf(props + strlen(props), "\\cfpat%d", (fmt->wShadingStyle >> 4) & 0xf);
720 if ((fmt->wShadingStyle >> 8) & 0xf)
721 sprintf(props + strlen(props), "\\cbpat%d", (fmt->wShadingStyle >> 8) & 0xf);
722 }
723 if (*props)
724 strcat(props, " ");
725
726 if (*props && !ME_StreamOutPrint(pStream, props))
727 return FALSE;
728
729 return TRUE;
730}
731
732
733static BOOL
735{
736 char props[STREAMOUT_BUFFER_SIZE] = "";
737 unsigned int i;
738 CHARFORMAT2W *old_fmt = &pStream->cur_fmt;
739 static const struct
740 {
741 DWORD effect;
742 const char *on, *off;
743 } effects[] =
744 {
745 { CFE_ALLCAPS, "\\caps", "\\caps0" },
746 { CFE_BOLD, "\\b", "\\b0" },
747 { CFE_DISABLED, "\\disabled", "\\disabled0" },
748 { CFE_EMBOSS, "\\embo", "\\embo0" },
749 { CFE_HIDDEN, "\\v", "\\v0" },
750 { CFE_IMPRINT, "\\impr", "\\impr0" },
751 { CFE_ITALIC, "\\i", "\\i0" },
752 { CFE_OUTLINE, "\\outl", "\\outl0" },
753 { CFE_PROTECTED, "\\protect", "\\protect0" },
754 { CFE_SHADOW, "\\shad", "\\shad0" },
755 { CFE_SMALLCAPS, "\\scaps", "\\scaps0" },
756 { CFE_STRIKEOUT, "\\strike", "\\strike0" },
757 };
758
759 for (i = 0; i < ARRAY_SIZE( effects ); i++)
760 {
761 if ((old_fmt->dwEffects ^ fmt->dwEffects) & effects[i].effect)
762 strcat( props, fmt->dwEffects & effects[i].effect ? effects[i].on : effects[i].off );
763 }
764
765 if ((old_fmt->dwEffects ^ fmt->dwEffects) & CFE_AUTOBACKCOLOR ||
766 (!(fmt->dwEffects & CFE_AUTOBACKCOLOR) && old_fmt->crBackColor != fmt->crBackColor))
767 {
768 if (fmt->dwEffects & CFE_AUTOBACKCOLOR) i = 0;
769 else find_color_in_colortbl( pStream, fmt->crBackColor, &i );
770 sprintf(props + strlen(props), "\\highlight%u", i);
771 }
772 if ((old_fmt->dwEffects ^ fmt->dwEffects) & CFE_AUTOCOLOR ||
773 (!(fmt->dwEffects & CFE_AUTOCOLOR) && old_fmt->crTextColor != fmt->crTextColor))
774 {
775 if (fmt->dwEffects & CFE_AUTOCOLOR) i = 0;
776 else find_color_in_colortbl( pStream, fmt->crTextColor, &i );
777 sprintf(props + strlen(props), "\\cf%u", i);
778 }
779
780 if (old_fmt->bAnimation != fmt->bAnimation)
781 sprintf(props + strlen(props), "\\animtext%u", fmt->bAnimation);
782 if (old_fmt->wKerning != fmt->wKerning)
783 sprintf(props + strlen(props), "\\kerning%u", fmt->wKerning);
784
785 if (old_fmt->lcid != fmt->lcid)
786 {
787 /* TODO: handle SFF_PLAINRTF */
788 if (LOWORD(fmt->lcid) == 1024)
789 strcat(props, "\\noproof\\lang1024\\langnp1024\\langfe1024\\langfenp1024");
790 else
791 sprintf(props + strlen(props), "\\lang%u", LOWORD(fmt->lcid));
792 }
793
794 if (old_fmt->yOffset != fmt->yOffset)
795 {
796 if (fmt->yOffset >= 0)
797 sprintf(props + strlen(props), "\\up%ld", fmt->yOffset);
798 else
799 sprintf(props + strlen(props), "\\dn%ld", -fmt->yOffset);
800 }
801 if (old_fmt->yHeight != fmt->yHeight)
802 sprintf(props + strlen(props), "\\fs%ld", fmt->yHeight / 10);
803 if (old_fmt->sSpacing != fmt->sSpacing)
804 sprintf(props + strlen(props), "\\expnd%u\\expndtw%u", fmt->sSpacing / 5, fmt->sSpacing);
805 if ((old_fmt->dwEffects ^ fmt->dwEffects) & (CFM_SUBSCRIPT | CFM_SUPERSCRIPT))
806 {
807 if (fmt->dwEffects & CFE_SUBSCRIPT)
808 strcat(props, "\\sub");
809 else if (fmt->dwEffects & CFE_SUPERSCRIPT)
810 strcat(props, "\\super");
811 else
812 strcat(props, "\\nosupersub");
813 }
814 if ((old_fmt->dwEffects ^ fmt->dwEffects) & CFE_UNDERLINE ||
815 old_fmt->bUnderlineType != fmt->bUnderlineType)
816 {
817 BYTE type = (fmt->dwEffects & CFE_UNDERLINE) ? fmt->bUnderlineType : CFU_UNDERLINENONE;
818 switch (type)
819 {
820 case CFU_UNDERLINE:
821 strcat(props, "\\ul");
822 break;
824 strcat(props, "\\uld");
825 break;
827 strcat(props, "\\uldb");
828 break;
830 strcat(props, "\\ulw");
831 break;
832 case CFU_CF1UNDERLINE:
834 default:
835 strcat(props, "\\ulnone");
836 break;
837 }
838 }
839
840 if (wcscmp(old_fmt->szFaceName, fmt->szFaceName) ||
841 old_fmt->bCharSet != fmt->bCharSet)
842 {
843 if (find_font_in_fonttbl( pStream, fmt, &i ))
844 {
845 sprintf(props + strlen(props), "\\f%u", i);
846
847 /* In UTF-8 mode, charsets/codepages are not used */
848 if (pStream->nDefaultCodePage != CP_UTF8)
849 {
850 if (pStream->fonttbl[i].bCharSet == DEFAULT_CHARSET)
851 pStream->nCodePage = pStream->nDefaultCodePage;
852 else
853 pStream->nCodePage = RTFCharSetToCodePage(NULL, pStream->fonttbl[i].bCharSet);
854 }
855 }
856 }
857 if (*props)
858 strcat(props, " ");
859 if (!ME_StreamOutPrint(pStream, props))
860 return FALSE;
861 *old_fmt = *fmt;
862 return TRUE;
863}
864
865
866static BOOL
868{
870 int pos = 0;
871 int fit, nBytes, i;
872
873 if (nChars == -1)
874 nChars = lstrlenW(text);
875
876 while (nChars) {
877 /* In UTF-8 mode, font charsets are not used. */
878 if (pStream->nDefaultCodePage == CP_UTF8) {
879 /* 6 is the maximum character length in UTF-8 */
880 fit = min(nChars, STREAMOUT_BUFFER_SIZE / 6);
881 nBytes = WideCharToMultiByte(CP_UTF8, 0, text, fit, buffer,
883 nChars -= fit;
884 text += fit;
885 for (i = 0; i < nBytes; i++)
886 if (buffer[i] == '{' || buffer[i] == '}' || buffer[i] == '\\') {
887 if (!ME_StreamOutPrint(pStream, "%.*s\\", i - pos, buffer + pos))
888 return FALSE;
889 pos = i;
890 }
891 if (pos < nBytes)
892 if (!ME_StreamOutMove(pStream, buffer + pos, nBytes - pos))
893 return FALSE;
894 pos = 0;
895 } else if (*text < 128) {
896 if (*text == '{' || *text == '}' || *text == '\\')
897 buffer[pos++] = '\\';
898 buffer[pos++] = (char)(*text++);
899 nChars--;
900 } else {
902 char letter[3];
903
904 /* FIXME: In the MS docs for WideCharToMultiByte there is a big list of
905 * codepages including CP_SYMBOL for which the last parameter must be set
906 * to NULL for the function to succeed. But in Wine we need to care only
907 * about CP_SYMBOL */
908 nBytes = WideCharToMultiByte(pStream->nCodePage, 0, text, 1,
909 letter, 3, NULL,
910 (pStream->nCodePage == CP_SYMBOL) ? NULL : &unknown);
911 if (unknown)
912 pos += sprintf(buffer + pos, "\\u%d?", (short)*text);
913 else if ((BYTE)*letter < 128) {
914 if (*letter == '{' || *letter == '}' || *letter == '\\')
915 buffer[pos++] = '\\';
916 buffer[pos++] = *letter;
917 } else {
918 for (i = 0; i < nBytes; i++)
919 pos += sprintf(buffer + pos, "\\'%02x", (BYTE)letter[i]);
920 }
921 text++;
922 nChars--;
923 }
924 if (pos >= STREAMOUT_BUFFER_SIZE - 11) {
925 if (!ME_StreamOutMove(pStream, buffer, pos))
926 return FALSE;
927 pos = 0;
928 }
929 }
930 return ME_StreamOutMove(pStream, buffer, pos);
931}
932
934 ME_Run *run )
935{
937 HRESULT hr;
938 FORMATETC fmt = { CF_ENHMETAFILE, NULL, DVASPECT_CONTENT, -1, TYMED_ENHMF };
939 STGMEDIUM med = { TYMED_NULL };
940 BOOL ret = FALSE;
941 ENHMETAHEADER *emf_bits = NULL;
942 UINT size;
943 SIZE goal, pic;
945 HDC hdc;
946
947 hr = IOleObject_QueryInterface( run->reobj->obj.poleobj, &IID_IDataObject, (void **)&data );
948 if (FAILED(hr)) return FALSE;
949
950 hdc = ITextHost_TxGetDC( editor->texthost );
951 ME_InitContext( &c, editor, hdc );
952 hr = IDataObject_QueryGetData( data, &fmt );
953 if (hr != S_OK) goto done;
954
955 hr = IDataObject_GetData( data, &fmt, &med );
956 if (FAILED(hr)) goto done;
957 if (med.tymed != TYMED_ENHMF) goto done;
958
959 size = GetEnhMetaFileBits( med.hEnhMetaFile, 0, NULL );
960 if (size < FIELD_OFFSET(ENHMETAHEADER, cbPixelFormat)) goto done;
961
962 emf_bits = malloc( size );
963 if (!emf_bits) goto done;
964
965 size = GetEnhMetaFileBits( med.hEnhMetaFile, size, (BYTE *)emf_bits );
966 if (size < FIELD_OFFSET(ENHMETAHEADER, cbPixelFormat)) goto done;
967
968 /* size_in_pixels = (frame_size / 100) * szlDevice / szlMillimeters
969 pic = size_in_pixels * 2540 / dpi */
970 pic.cx = MulDiv( emf_bits->rclFrame.right - emf_bits->rclFrame.left, emf_bits->szlDevice.cx * 254,
971 emf_bits->szlMillimeters.cx * c.dpi.cx * 10 );
972 pic.cy = MulDiv( emf_bits->rclFrame.bottom - emf_bits->rclFrame.top, emf_bits->szlDevice.cy * 254,
973 emf_bits->szlMillimeters.cy * c.dpi.cy * 10 );
974
975 /* convert goal size to twips */
976 goal.cx = MulDiv( run->reobj->obj.sizel.cx, 144, 254 );
977 goal.cy = MulDiv( run->reobj->obj.sizel.cy, 144, 254 );
978
979 if (!ME_StreamOutPrint( stream, "{\\*\\shppict{\\pict\\emfblip\\picw%d\\pich%d\\picwgoal%d\\pichgoal%d\n",
980 pic.cx, pic.cy, goal.cx, goal.cy ))
981 goto done;
982
983 if (!ME_StreamOutHexData( stream, (BYTE *)emf_bits, size ))
984 goto done;
985
986 if (!ME_StreamOutPrint( stream, "}}\n" ))
987 goto done;
988
989 ret = TRUE;
990
991done:
994 free( emf_bits );
995 ReleaseStgMedium( &med );
996 IDataObject_Release( data );
997 return ret;
998}
999
1001 const ME_Cursor *start, int nChars, int dwFormat)
1002{
1004 ME_Paragraph *prev_para = NULL;
1005 ME_Cursor endCur = cursor;
1006
1007 ME_MoveCursorChars(editor, &endCur, nChars, TRUE);
1008
1009 if (!ME_StreamOutRTFHeader(pStream, dwFormat))
1010 return FALSE;
1011
1012 if (!stream_out_font_and_colour_tbls( pStream, cursor.run, endCur.run ))
1013 return FALSE;
1014
1015 /* TODO: stylesheet table */
1016
1017 if (!ME_StreamOutPrint(pStream, "{\\*\\generator Wine Riched20 2.0;}\r\n"))
1018 return FALSE;
1019
1020 /* TODO: information group */
1021
1022 /* TODO: document formatting properties */
1023
1024 /* FIXME: We have only one document section */
1025
1026 /* TODO: section formatting properties */
1027
1028 do
1029 {
1030 if (cursor.para != prev_para)
1031 {
1032 prev_para = cursor.para;
1033 if (!stream_out_para_props( editor, pStream, cursor.para ))
1034 return FALSE;
1035 }
1036
1037 if (cursor.run == endCur.run && !endCur.nOffset)
1038 break;
1039
1040 TRACE("flags %xh\n", cursor.run->nFlags);
1041 /* TODO: emit embedded objects */
1042 if (cursor.para->nFlags & (MEPF_ROWSTART | MEPF_ROWEND))
1043 continue;
1044 if (cursor.run->nFlags & MERF_GRAPHICS)
1045 {
1046 if (!stream_out_graphics( editor, pStream, cursor.run ))
1047 return FALSE;
1048 }
1049 else if (cursor.run->nFlags & MERF_TAB)
1050 {
1051 if (editor->bEmulateVersion10 && /* v1.0 - 3.0 */
1052 para_in_table( cursor.para ))
1053 {
1054 if (!ME_StreamOutPrint(pStream, "\\cell "))
1055 return FALSE;
1056 }
1057 else
1058 {
1059 if (!ME_StreamOutPrint(pStream, "\\tab "))
1060 return FALSE;
1061 }
1062 }
1063 else if (cursor.run->nFlags & MERF_ENDCELL)
1064 {
1065 if (pStream->nNestingLevel > 1)
1066 {
1067 if (!ME_StreamOutPrint(pStream, "\\nestcell "))
1068 return FALSE;
1069 }
1070 else
1071 {
1072 if (!ME_StreamOutPrint(pStream, "\\cell "))
1073 return FALSE;
1074 }
1075 nChars--;
1076 }
1077 else if (cursor.run->nFlags & MERF_ENDPARA)
1078 {
1079 if (!ME_StreamOutRTFCharProps( pStream, &cursor.run->style->fmt ))
1080 return FALSE;
1081
1082 if (para_in_table( cursor.para ) &&
1083 !(cursor.para->nFlags & (MEPF_ROWSTART | MEPF_ROWEND | MEPF_CELL)))
1084 {
1085 if (!ME_StreamOutPrint(pStream, "\\row\r\n"))
1086 return FALSE;
1087 }
1088 else
1089 {
1090 if (!ME_StreamOutPrint(pStream, "\\par\r\n"))
1091 return FALSE;
1092 }
1093 /* Skip as many characters as required by current line break */
1094 nChars = max(0, nChars - cursor.run->len);
1095 }
1096 else if (cursor.run->nFlags & MERF_ENDROW)
1097 {
1098 if (!ME_StreamOutPrint(pStream, "\\line\r\n"))
1099 return FALSE;
1100 nChars--;
1101 }
1102 else
1103 {
1104 int nEnd;
1105
1106 TRACE("style %p\n", cursor.run->style);
1107 if (!ME_StreamOutRTFCharProps( pStream, &cursor.run->style->fmt ))
1108 return FALSE;
1109
1110 nEnd = (cursor.run == endCur.run) ? endCur.nOffset : cursor.run->len;
1111 if (!ME_StreamOutRTFText(pStream, get_text( cursor.run, cursor.nOffset ),
1112 nEnd - cursor.nOffset))
1113 return FALSE;
1114 cursor.nOffset = 0;
1115 }
1116 } while (cursor.run != endCur.run && cursor_next_run( &cursor, TRUE ));
1117
1118 if (!ME_StreamOutMove(pStream, "}\0", 2))
1119 return FALSE;
1120 return TRUE;
1121}
1122
1123
1125 const ME_Cursor *start, int nChars, DWORD dwFormat)
1126{
1128 int nLen;
1129 UINT nCodePage = CP_ACP;
1130 char *buffer = NULL;
1131 int nBufLen = 0;
1132 BOOL success = TRUE;
1133
1134 if (!cursor.run)
1135 return FALSE;
1136
1137 if (dwFormat & SF_USECODEPAGE)
1138 nCodePage = HIWORD(dwFormat);
1139
1140 /* TODO: Handle SF_TEXTIZED */
1141
1142 while (success && nChars && cursor.run)
1143 {
1144 nLen = min(nChars, cursor.run->len - cursor.nOffset);
1145
1146 if (!editor->bEmulateVersion10 && cursor.run->nFlags & MERF_ENDPARA)
1147 {
1148 /* richedit 2.0 - all line breaks are \r\n */
1149 if (dwFormat & SF_UNICODE)
1150 success = ME_StreamOutMove(pStream, (const char *)L"\r\n", 2 * sizeof(WCHAR));
1151 else
1152 success = ME_StreamOutMove(pStream, "\r\n", 2);
1153 } else {
1154 if (dwFormat & SF_UNICODE)
1155 success = ME_StreamOutMove(pStream, (const char *)(get_text( cursor.run, cursor.nOffset )),
1156 sizeof(WCHAR) * nLen);
1157 else {
1158 int nSize;
1159
1160 nSize = WideCharToMultiByte(nCodePage, 0, get_text( cursor.run, cursor.nOffset ),
1161 nLen, NULL, 0, NULL, NULL);
1162 if (nSize > nBufLen) {
1164 nBufLen = nSize;
1165 }
1166 WideCharToMultiByte(nCodePage, 0, get_text( cursor.run, cursor.nOffset ),
1167 nLen, buffer, nSize, NULL, NULL);
1168 success = ME_StreamOutMove(pStream, buffer, nSize);
1169 }
1170 }
1171
1172 nChars -= nLen;
1173 cursor.nOffset = 0;
1174 cursor.run = run_next_all_paras( cursor.run );
1175 }
1176
1177 free(buffer);
1178 return success;
1179}
1180
1181
1183 const ME_Cursor *start,
1184 int nChars, EDITSTREAM *stream)
1185{
1186 ME_OutStream *pStream = ME_StreamOutInit(editor, stream);
1187
1188 if (dwFormat & SF_RTF)
1189 ME_StreamOutRTF(editor, pStream, start, nChars, dwFormat);
1190 else if (dwFormat & SF_TEXT || dwFormat & SF_TEXTIZED)
1191 ME_StreamOutText(editor, pStream, start, nChars, dwFormat);
1192 if (!pStream->stream->dwError)
1193 ME_StreamOutFlush(pStream);
1194 return ME_StreamOutFree(pStream);
1195}
1196
1197LRESULT
1199{
1201 int nChars;
1202
1203 if (dwFormat & SFF_SELECTION) {
1204 LONG nStart, nTo;
1205 start = editor->pCursors[ME_GetSelectionOfs(editor, &nStart, &nTo)];
1206 nChars = nTo - nStart;
1207 } else {
1208 ME_SetCursorToStart(editor, &start);
1209 nChars = ME_GetTextLength(editor);
1210 /* Generate an end-of-paragraph at the end of SCF_ALL RTF output */
1211 if (dwFormat & SF_RTF)
1212 nChars++;
1213 }
1214 return ME_StreamOutRange(editor, dwFormat, &start, nChars, stream);
1215}
ios_base &_STLP_CALL dec(ios_base &__s)
Definition: _ios_base.h:321
ios_base &_STLP_CALL hex(ios_base &__s)
Definition: _ios_base.h:324
#define vsnprintf
Definition: acwin.h:108
Arabic default style
Definition: afstyles.h:94
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define CF_ENHMETAFILE
Definition: constants.h:409
#define ARRAY_SIZE(A)
Definition: main.h:20
CFF_Charset charset
Definition: cffcmap.c:137
#define realloc
Definition: debug_ros.c:6
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
HRESULT hr
Definition: delayimp.cpp:582
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
WORD face[3]
Definition: mesh.c:4747
unsigned int idx
Definition: utils.c:41
static WCHAR unknown[MAX_STRING_RESOURCE_LEN]
Definition: object.c:1674
#define CP_ACP
Definition: compat.h:109
static __inline const char * debugstr_an(const char *s, int n)
Definition: compat.h:55
#define WideCharToMultiByte
Definition: compat.h:111
#define lstrlenW
Definition: compat.h:750
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
const WCHAR * text
Definition: package.c:1794
#define assert(_expr)
Definition: assert.h:32
_ACRTIMP int __cdecl wcscmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:1977
_ACRTIMP int __cdecl memcmp(const void *, const void *, size_t)
Definition: string.c:2807
#define va_end(v)
Definition: stdarg.h:28
#define va_start(v, l)
Definition: stdarg.h:26
_ACRTIMP size_t __cdecl strlen(const char *)
Definition: string.c:1597
char * va_list
Definition: vadefs.h:50
void WINAPI ReleaseStgMedium(STGMEDIUM *pmedium)
Definition: ole2.c:2014
void ME_SetCursorToStart(ME_TextEditor *editor, ME_Cursor *cursor)
Definition: caret.c:27
int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs, BOOL final_eop)
Definition: caret.c:709
int ME_GetSelectionOfs(ME_TextEditor *editor, LONG *from, LONG *to)
Definition: caret.c:42
int ME_GetTextLength(ME_TextEditor *editor)
Definition: caret.c:83
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
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
#define HEX_BYTES_PER_LINE
Definition: writer.c:135
#define STREAMOUT_BUFFER_SIZE
Definition: writer.c:26
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 void add_color_to_colortbl(ME_OutStream *stream, COLORREF color)
Definition: writer.c:280
static BOOL ME_StreamOutRTFHeader(ME_OutStream *pStream, int dwFormat)
Definition: writer.c:163
LRESULT ME_StreamOutRange(ME_TextEditor *editor, DWORD dwFormat, const ME_Cursor *start, int nChars, EDITSTREAM *stream)
Definition: writer.c:1182
struct tagME_OutStream ME_OutStream
static BOOL find_color_in_colortbl(ME_OutStream *stream, COLORREF color, unsigned int *idx)
Definition: writer.c:295
static BOOL ME_StreamOutRTFCharProps(ME_OutStream *pStream, CHARFORMAT2W *fmt)
Definition: writer.c:734
static BOOL ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream, const ME_Cursor *start, int nChars, DWORD dwFormat)
Definition: writer.c:1124
static BOOL ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream, const ME_Cursor *start, int nChars, int dwFormat)
Definition: writer.c:1000
static BOOL ME_StreamOutHexData(ME_OutStream *stream, const BYTE *data, UINT len)
Definition: writer.c:138
static BOOL stream_out_font_and_colour_tbls(ME_OutStream *pStream, ME_Run *first, ME_Run *last)
Definition: writer.c:312
LRESULT ME_StreamOut(ME_TextEditor *editor, DWORD dwFormat, EDITSTREAM *stream)
Definition: writer.c:1198
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:933
static void add_font_to_fonttbl(ME_OutStream *stream, ME_Style *style)
Definition: writer.c:231
static BOOL stream_out_table_props(ME_TextEditor *editor, ME_OutStream *pStream, ME_Paragraph *para)
Definition: writer.c:385
#define STREAMOUT_COLORTBL_SIZE
Definition: writer.c:28
static BOOL stream_out_para_num(ME_OutStream *stream, ME_Paragraph *para, BOOL pn_dest)
Definition: writer.c:462
static BOOL ME_StreamOutRTFText(ME_OutStream *pStream, const WCHAR *text, LONG nChars)
Definition: writer.c:867
#define STREAMOUT_FONTTBL_SIZE
Definition: writer.c:27
static BOOL ME_StreamOutFlush(ME_OutStream *pStream)
Definition: writer.c:67
static BOOL ME_StreamOutMove(ME_OutStream *pStream, const char *buffer, int len)
Definition: writer.c:101
unsigned char
Definition: typeof.h:29
return ret
Definition: mutex.c:146
#define L(x)
Definition: resources.c:13
switch(r->id)
Definition: btrfs.c:3046
ME_Cell * cell_next(ME_Cell *cell)
Definition: table.c:192
BOOL cursor_next_run(ME_Cursor *cursor, BOOL all_para)
Definition: run.c:30
ME_Cell * table_row_first_cell(ME_Paragraph *para)
Definition: table.c:170
ME_Cell * para_cell(ME_Paragraph *para)
Definition: para.c:127
ME_Paragraph * table_row_end(ME_Paragraph *para)
Definition: table.c:127
#define ITextHost_TxGetDC(This)
Definition: editor.h:332
BOOL para_in_table(ME_Paragraph *para)
Definition: para.c:122
#define ITextHost_TxReleaseDC(This, a)
Definition: editor.h:333
ME_Paragraph * para_prev(ME_Paragraph *para)
Definition: para.c:63
static WCHAR * get_text(const ME_Run *run, int offset)
Definition: editor.h:41
ME_Run * run_next_all_paras(ME_Run *run)
Definition: run.c:96
#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
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint start
Definition: gl.h:1545
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLint GLint GLsizei width
Definition: gl.h:1546
GLuint buffer
Definition: glext.h:5915
GLsizeiptr size
Definition: glext.h:5919
GLuint color
Definition: glext.h:6243
const GLubyte * c
Definition: glext.h:8905
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
const GLint * first
Definition: glext.h:5794
GLenum GLsizei len
Definition: glext.h:6722
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
unsigned int UINT
Definition: sysinfo.c:13
const char cursor[]
Definition: icontest.c:13
#define S_OK
Definition: intsafe.h:52
#define FAILED(hr)
Definition: intsafe.h:51
#define c
Definition: ke_i.h:80
USHORT LANGID
Definition: mui.h:9
if(dx< 0)
Definition: linetemp.h:194
LONG_PTR LRESULT
Definition: minwindef.h:176
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define sprintf
Definition: sprintf.c:45
HDC hdc
Definition: main.c:9
static HDC
Definition: imagelist.c:88
static const LARGE_INTEGER *static const HANDLE const LARGE_INTEGER *static PSLIST_ENTRY PSLIST_ENTRY last
Definition: sync.c:64
static va_list valist
Definition: printf.c:46
#define min(a, b)
Definition: monoChain.cc:55
INT WINAPI MulDiv(INT nNumber, INT nNumerator, INT nDenominator)
Definition: muldiv.c:25
const GUID IID_IDataObject
#define LOWORD(l)
Definition: pedump.c:82
short WCHAR
Definition: pedump.c:58
long LONG
Definition: pedump.c:60
#define PFN_UCLETTER
Definition: richedit.h:908
#define CFU_UNDERLINEDOUBLE
Definition: richedit.h:430
#define PFA_RIGHT
Definition: richedit.h:922
#define SFF_SELECTION
Definition: richedit.h:979
#define PFA_CENTER
Definition: richedit.h:923
#define PFE_RTLPARA
Definition: richedit.h:932
#define CFE_SMALLCAPS
Definition: richedit.h:416
#define PFE_KEEP
Definition: richedit.h:933
#define PFE_DONOTHYPHEN
Definition: richedit.h:938
#define PFN_ARABIC
Definition: richedit.h:906
#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 SF_USECODEPAGE
Definition: richedit.h:725
#define PFE_NOWIDOWCONTROL
Definition: richedit.h:937
#define PFA_LEFT
Definition: richedit.h:921
#define CFE_AUTOCOLOR
Definition: richedit.h:414
#define PFM_NOLINENUMBER
Definition: richedit.h:860
#define PFM_KEEPNEXT
Definition: richedit.h:858
#define CFU_UNDERLINEWORD
Definition: richedit.h:429
#define PFM_DONOTHYPHEN
Definition: richedit.h:862
#define CFE_ALLCAPS
Definition: richedit.h:417
#define SF_RTF
Definition: richedit.h:721
#define CFE_ITALIC
Definition: richedit.h:407
#define PFM_LINESPACING
Definition: richedit.h:849
#define CFE_DISABLED
Definition: richedit.h:423
#define PFN_LCLETTER
Definition: richedit.h:907
#define CFE_SUPERSCRIPT
Definition: richedit.h:413
#define CFM_SUBSCRIPT
Definition: richedit.h:348
#define CFE_IMPRINT
Definition: richedit.h:422
#define PFN_UCROMAN
Definition: richedit.h:910
#define CFM_CHARSET
Definition: richedit.h:358
#define PFM_SHADING
Definition: richedit.h:852
#define CFE_UNDERLINE
Definition: richedit.h:408
#define CFM_BACKCOLOR
Definition: richedit.h:357
#define CFE_SUBSCRIPT
Definition: richedit.h:412
#define PFM_TABLE
Definition: richedit.h:870
#define PFNS_PAREN
Definition: richedit.h:913
#define PFN_BULLET
Definition: richedit.h:905
#define CFU_UNDERLINE
Definition: richedit.h:428
#define CFE_PROTECTED
Definition: richedit.h:410
#define PFE_SIDEBYSIDE
Definition: richedit.h:939
#define PFM_NOWIDOWCONTROL
Definition: richedit.h:861
#define CFE_EMBOSS
Definition: richedit.h:421
#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 SF_TEXT
Definition: richedit.h:720
#define CFE_AUTOBACKCOLOR
Definition: richedit.h:425
#define PFM_SIDEBYSIDE
Definition: richedit.h:863
#define PFA_JUSTIFY
Definition: richedit.h:924
#define PFM_TABSTOPS
Definition: richedit.h:842
#define PFN_LCROMAN
Definition: richedit.h:909
#define SF_UNICODE
Definition: richedit.h:724
#define PFNS_PARENS
Definition: richedit.h:914
#define CFU_CF1UNDERLINE
Definition: richedit.h:447
#define PFM_KEEP
Definition: richedit.h:857
#define CFU_UNDERLINENONE
Definition: richedit.h:427
#define CFM_FACE
Definition: richedit.h:360
#define CFE_SHADOW
Definition: richedit.h:420
#define PFM_RTLPARA
Definition: richedit.h:856
#define PFE_KEEPNEXT
Definition: richedit.h:934
#define CFU_UNDERLINEDOTTED
Definition: richedit.h:431
#define CFM_COLOR
Definition: richedit.h:361
#define SF_TEXTIZED
Definition: richedit.h:723
#define PFNS_PERIOD
Definition: richedit.h:915
#define CFM_SUPERSCRIPT
Definition: richedit.h:349
#define calloc
Definition: rosglue.h:14
#define WINAPIV
Definition: sdbpapi.h:64
#define CP_UTF8
Definition: nls.h:20
strcat
Definition: string.h:92
#define TRACE(s)
Definition: solgame.cpp:4
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
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
DWORD dwEffects
Definition: richedit.h:307
SHORT sSpacing
Definition: richedit.h:315
BYTE bUnderlineType
Definition: richedit.h:321
LONG yHeight
Definition: richedit.h:308
COLORREF crBackColor
Definition: richedit.h:316
COLORREF crTextColor
Definition: richedit.h:310
DWORD dwError
Definition: richedit.h:523
WORD wNumberingStart
Definition: richedit.h:680
DWORD dwMask
Definition: richedit.h:667
WORD wNumberingStyle
Definition: richedit.h:680
LONG dxOffset
Definition: richedit.h:672
LONG rgxTabs[MAX_TAB_STOPS]
Definition: richedit.h:675
WORD wNumbering
Definition: richedit.h:668
SHORT cTabCount
Definition: richedit.h:674
WORD wEffects
Definition: richedit.h:669
LONG dxStartIndent
Definition: richedit.h:670
WORD wNumberingTab
Definition: richedit.h:680
Definition: dsound.c:943
Definition: format.c:58
Definition: parser.c:49
Definition: parse.h:23
RECTL rclFrame
Definition: wingdi.h:2769
SIZEL szlDevice
Definition: wingdi.h:2779
SIZEL szlMillimeters
Definition: wingdi.h:2780
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
COLORREF colorRef
Definition: editstr.h:183
int nRightBoundary
Definition: editstr.h:224
ME_BorderRect border
Definition: editstr.h:225
int nOffset
Definition: editstr.h:277
ME_Run * run
Definition: editstr.h:276
EDITSTREAM * stream
Definition: writer.c:32
COLORREF colortbl[STREAMOUT_COLORTBL_SIZE]
Definition: writer.c:39
UINT nFontTblLen
Definition: writer.c:36
UINT written
Definition: writer.c:34
ME_FontTableItem fonttbl[STREAMOUT_FONTTBL_SIZE]
Definition: writer.c:37
CHARFORMAT2W cur_fmt
Definition: writer.c:45
UINT nCodePage
Definition: writer.c:35
UINT nDefaultFont
Definition: writer.c:40
UINT nNestingLevel
Definition: writer.c:44
UINT nColorTblLen
Definition: writer.c:38
char buffer[STREAMOUT_BUFFER_SIZE]
Definition: writer.c:33
UINT nDefaultCodePage
Definition: writer.c:41
struct para_num para_num
Definition: editstr.h:215
ME_BorderRect border
Definition: editstr.h:208
PARAFORMAT2 fmt
Definition: editstr.h:204
struct tagME_Paragraph * para
Definition: editstr.h:161
ME_Style * style
Definition: editstr.h:160
struct re_object * reobj
Definition: editstr.h:168
CHARFORMAT2W fmt
Definition: editstr.h:71
ITextHost2 * texthost
Definition: editstr.h:391
ME_Cursor * pCursors
Definition: editstr.h:396
unsigned int bEmulateVersion10
Definition: editstr.h:392
#define max(a, b)
Definition: svc.c:63
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * LPBYTE
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define HIWORD(l)
Definition: typedefs.h:247
static const WCHAR props[]
Definition: wbemdisp.c:288
#define success(from, fromstr, to, tostr)
*nSize LPSTR _Inout_ LPDWORD nSize
Definition: winbase.h:1811
DWORD COLORREF
Definition: windef.h:100
UINT WINAPI GetEnhMetaFileBits(_In_ HENHMETAFILE hEMF, _In_ UINT nSize, _Out_writes_bytes_opt_(nSize) LPBYTE lpData)
#define DEFAULT_CHARSET
Definition: wingdi.h:384
#define CP_OEMCP
Definition: winnls.h:259
#define CP_SYMBOL
Definition: winnls.h:262
#define CP_MACCP
Definition: winnls.h:260
unsigned char BYTE
Definition: xxhash.c:193