ReactOS 0.4.15-dev-7961-gdcf9eb0
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#define NONAMELESSUNION
22
23#include "editor.h"
24#include "rtf.h"
25
27
28#define STREAMOUT_BUFFER_SIZE 4096
29#define STREAMOUT_FONTTBL_SIZE 8192
30#define STREAMOUT_COLORTBL_SIZE 1024
31
32typedef struct tagME_OutStream
33{
44 /* nNestingLevel = 0 means we aren't in a cell, 1 means we are in a cell,
45 * an greater numbers mean we are in a cell nested within a cell. */
47 CHARFORMAT2W cur_fmt; /* current character format */
49
50static BOOL
51ME_StreamOutRTFText(ME_OutStream *pStream, const WCHAR *text, LONG nChars);
52
53
54static ME_OutStream*
56{
57 ME_OutStream *pStream = heap_alloc_zero(sizeof(*pStream));
58
59 pStream->stream = stream;
60 pStream->stream->dwError = 0;
61 pStream->nColorTblLen = 1;
64 return pStream;
65}
66
67
68static BOOL
70{
71 LONG nWritten = 0;
72 EDITSTREAM *stream = pStream->stream;
73
74 if (pStream->pos) {
75 TRACE("sending %u bytes\n", pStream->pos);
76 nWritten = pStream->pos;
77 stream->dwError = stream->pfnCallback(stream->dwCookie, (LPBYTE)pStream->buffer,
78 pStream->pos, &nWritten);
79 TRACE("error=%u written=%u\n", stream->dwError, nWritten);
80 if (nWritten == 0 || stream->dwError)
81 return FALSE;
82 /* Don't resend partial chunks if nWritten < pStream->pos */
83 }
84 if (nWritten == pStream->pos)
85 pStream->written += nWritten;
86 pStream->pos = 0;
87 return TRUE;
88}
89
90
91static LONG
93{
94 LONG written = pStream->written;
95 TRACE("total length = %u\n", written);
96
97 heap_free(pStream);
98 return written;
99}
100
101
102static BOOL
103ME_StreamOutMove(ME_OutStream *pStream, const char *buffer, int len)
104{
105 while (len) {
106 int space = STREAMOUT_BUFFER_SIZE - pStream->pos;
107 int fit = min(space, len);
108
109 TRACE("%u:%u:%s\n", pStream->pos, fit, debugstr_an(buffer,fit));
110 memmove(pStream->buffer + pStream->pos, buffer, fit);
111 len -= fit;
112 buffer += fit;
113 pStream->pos += fit;
114 if (pStream->pos == STREAMOUT_BUFFER_SIZE) {
115 if (!ME_StreamOutFlush(pStream))
116 return FALSE;
117 }
118 }
119 return TRUE;
120}
121
122
123static BOOL WINAPIV
124ME_StreamOutPrint(ME_OutStream *pStream, const char *format, ...)
125{
126 char string[STREAMOUT_BUFFER_SIZE]; /* This is going to be enough */
127 int len;
129
131 len = vsnprintf(string, sizeof(string), format, valist);
133
134 return ME_StreamOutMove(pStream, string, len);
135}
136
137#define HEX_BYTES_PER_LINE 40
138
139static BOOL
141{
142
143 char line[HEX_BYTES_PER_LINE * 2 + 1];
144 UINT size, i;
145 static const char hex[] = "0123456789abcdef";
146
147 while (len)
148 {
150 for (i = 0; i < size; i++)
151 {
152 line[i * 2] = hex[(*data >> 4) & 0xf];
153 line[i * 2 + 1] = hex[*data & 0xf];
154 data++;
155 }
156 line[size * 2] = '\n';
157 if (!ME_StreamOutMove( stream, line, size * 2 + 1 ))
158 return FALSE;
159 len -= size;
160 }
161 return TRUE;
162}
163
164static BOOL
165ME_StreamOutRTFHeader(ME_OutStream *pStream, int dwFormat)
166{
167 const char *cCharSet = NULL;
168 UINT nCodePage;
169 LANGID language;
171
172 if (dwFormat & SF_USECODEPAGE) {
174
175 switch (HIWORD(dwFormat)) {
176 case CP_ACP:
177 cCharSet = "ansi";
178 nCodePage = GetACP();
179 break;
180 case CP_OEMCP:
181 nCodePage = GetOEMCP();
182 if (nCodePage == 437)
183 cCharSet = "pc";
184 else if (nCodePage == 850)
185 cCharSet = "pca";
186 else
187 cCharSet = "ansi";
188 break;
189 case CP_UTF8:
190 nCodePage = CP_UTF8;
191 break;
192 default:
193 if (HIWORD(dwFormat) == CP_MACCP) {
194 cCharSet = "mac";
195 nCodePage = 10000; /* MacRoman */
196 } else {
197 cCharSet = "ansi";
198 nCodePage = 1252; /* Latin-1 */
199 }
200 if (GetCPInfoExW(HIWORD(dwFormat), 0, &info))
201 nCodePage = info.CodePage;
202 }
203 } else {
204 cCharSet = "ansi";
205 /* TODO: If the original document contained an \ansicpg value, retain it.
206 * Otherwise, M$ richedit emits a codepage number determined from the
207 * charset of the default font here. Anyway, this value is not used by
208 * the reader... */
209 nCodePage = GetACP();
210 }
211 if (nCodePage == CP_UTF8)
212 success = ME_StreamOutPrint(pStream, "{\\urtf");
213 else
214 success = ME_StreamOutPrint(pStream, "{\\rtf1\\%s\\ansicpg%u\\uc1", cCharSet, nCodePage);
215
216 if (!success)
217 return FALSE;
218
219 pStream->nDefaultCodePage = nCodePage;
220
221 /* FIXME: This should be a document property */
222 /* TODO: handle SFF_PLAINRTF */
223 language = GetUserDefaultLangID();
224 if (!ME_StreamOutPrint(pStream, "\\deff0\\deflang%u\\deflangfe%u", language, language))
225 return FALSE;
226
227 /* FIXME: This should be a document property */
228 pStream->nDefaultFont = 0;
229
230 return TRUE;
231}
232
234{
235 ME_FontTableItem *table = stream->fonttbl;
236 CHARFORMAT2W *fmt = &style->fmt;
237 WCHAR *face = fmt->szFaceName;
238 BYTE charset = (fmt->dwMask & CFM_CHARSET) ? fmt->bCharSet : DEFAULT_CHARSET;
239 int i;
240
241 if (fmt->dwMask & CFM_FACE)
242 {
243 for (i = 0; i < stream->nFontTblLen; i++)
244 if (table[i].bCharSet == charset
245 && (table[i].szFaceName == face || !wcscmp(table[i].szFaceName, face)))
246 break;
247
248 if (i == stream->nFontTblLen && i < STREAMOUT_FONTTBL_SIZE)
249 {
250 table[i].bCharSet = charset;
251 table[i].szFaceName = face;
252 stream->nFontTblLen++;
253 }
254 }
255}
256
258{
259 WCHAR *facename;
260 int i;
261
262 *idx = 0;
263 if (fmt->dwMask & CFM_FACE)
264 facename = fmt->szFaceName;
265 else
266 facename = stream->fonttbl[0].szFaceName;
267 for (i = 0; i < stream->nFontTblLen; i++)
268 {
269 if (facename == stream->fonttbl[i].szFaceName
270 || !wcscmp(facename, stream->fonttbl[i].szFaceName))
271 if (!(fmt->dwMask & CFM_CHARSET)
272 || fmt->bCharSet == stream->fonttbl[i].bCharSet)
273 {
274 *idx = i;
275 break;
276 }
277 }
278
279 return i < stream->nFontTblLen;
280}
281
283{
284 int i;
285
286 for (i = 1; i < stream->nColorTblLen; i++)
287 if (stream->colortbl[i] == color)
288 break;
289
290 if (i == stream->nColorTblLen && i < STREAMOUT_COLORTBL_SIZE)
291 {
292 stream->colortbl[i] = color;
293 stream->nColorTblLen++;
294 }
295}
296
298{
299 int i;
300
301 *idx = 0;
302 for (i = 1; i < stream->nColorTblLen; i++)
303 {
304 if (stream->colortbl[i] == color)
305 {
306 *idx = i;
307 break;
308 }
309 }
310
311 return i < stream->nFontTblLen;
312}
313
314static BOOL
316 ME_DisplayItem *pLastRun)
317{
318 ME_DisplayItem *item = pFirstRun;
319 ME_FontTableItem *table = pStream->fonttbl;
320 unsigned int i;
321 ME_DisplayItem *pCell = NULL;
322 ME_Paragraph *prev_para = NULL;
323
324 do {
325 CHARFORMAT2W *fmt = &item->member.run.style->fmt;
326
327 add_font_to_fonttbl( pStream, item->member.run.style );
328
329 if (fmt->dwMask & CFM_COLOR && !(fmt->dwEffects & CFE_AUTOCOLOR))
330 add_color_to_colortbl( pStream, fmt->crTextColor );
331 if (fmt->dwMask & CFM_BACKCOLOR && !(fmt->dwEffects & CFE_AUTOBACKCOLOR))
332 add_color_to_colortbl( pStream, fmt->crBackColor );
333
334 if (item->member.run.para != prev_para)
335 {
336 /* check for any para numbering text */
337 if (item->member.run.para->fmt.wNumbering)
338 add_font_to_fonttbl( pStream, item->member.run.para->para_num.style );
339
340 if ((pCell = item->member.para.pCell))
341 {
342 ME_Border* borders[4] = { &pCell->member.cell.border.top,
343 &pCell->member.cell.border.left,
344 &pCell->member.cell.border.bottom,
345 &pCell->member.cell.border.right };
346 for (i = 0; i < 4; i++)
347 if (borders[i]->width > 0)
348 add_color_to_colortbl( pStream, borders[i]->colorRef );
349 }
350
351 prev_para = item->member.run.para;
352 }
353
354 if (item == pLastRun)
355 break;
357 } while (item);
358
359 if (!ME_StreamOutPrint(pStream, "{\\fonttbl"))
360 return FALSE;
361
362 for (i = 0; i < pStream->nFontTblLen; i++) {
363 if (table[i].bCharSet != DEFAULT_CHARSET) {
364 if (!ME_StreamOutPrint(pStream, "{\\f%u\\fcharset%u ", i, table[i].bCharSet))
365 return FALSE;
366 } else {
367 if (!ME_StreamOutPrint(pStream, "{\\f%u ", i))
368 return FALSE;
369 }
370 if (!ME_StreamOutRTFText(pStream, table[i].szFaceName, -1))
371 return FALSE;
372 if (!ME_StreamOutPrint(pStream, ";}"))
373 return FALSE;
374 }
375 if (!ME_StreamOutPrint(pStream, "}\r\n"))
376 return FALSE;
377
378 /* Output the color table */
379 if (!ME_StreamOutPrint(pStream, "{\\colortbl;")) return FALSE; /* first entry is auto-color */
380 for (i = 1; i < pStream->nColorTblLen; i++)
381 {
382 if (!ME_StreamOutPrint(pStream, "\\red%u\\green%u\\blue%u;", pStream->colortbl[i] & 0xFF,
383 (pStream->colortbl[i] >> 8) & 0xFF, (pStream->colortbl[i] >> 16) & 0xFF))
384 return FALSE;
385 }
386 if (!ME_StreamOutPrint(pStream, "}\r\n")) return FALSE;
387
388 return TRUE;
389}
390
391static BOOL
393 ME_DisplayItem *para)
394{
395 ME_DisplayItem *cell;
396 char props[STREAMOUT_BUFFER_SIZE] = "";
397 int i;
398 const char sideChar[4] = {'t','l','b','r'};
399
400 if (!ME_StreamOutPrint(pStream, "\\trowd"))
401 return FALSE;
402 if (!editor->bEmulateVersion10) { /* v4.1 */
404 para = ME_GetTableRowStart(para);
405 cell = para->member.para.next_para->member.para.pCell;
406 assert(cell);
407 if (pFmt->dxOffset)
408 sprintf(props + strlen(props), "\\trgaph%d", pFmt->dxOffset);
409 if (pFmt->dxStartIndent)
410 sprintf(props + strlen(props), "\\trleft%d", pFmt->dxStartIndent);
411 do {
412 ME_Border* borders[4] = { &cell->member.cell.border.top,
413 &cell->member.cell.border.left,
414 &cell->member.cell.border.bottom,
415 &cell->member.cell.border.right };
416 for (i = 0; i < 4; i++)
417 {
418 if (borders[i]->width)
419 {
420 unsigned int idx;
421 COLORREF crColor = borders[i]->colorRef;
422 sprintf(props + strlen(props), "\\clbrdr%c", sideChar[i]);
423 sprintf(props + strlen(props), "\\brdrs");
424 sprintf(props + strlen(props), "\\brdrw%d", borders[i]->width);
425 if (find_color_in_colortbl( pStream, crColor, &idx ))
426 sprintf(props + strlen(props), "\\brdrcf%u", idx);
427 }
428 }
429 sprintf(props + strlen(props), "\\cellx%d", cell->member.cell.nRightBoundary);
430 cell = cell->member.cell.next_cell;
431 } while (cell->member.cell.next_cell);
432 } else { /* v1.0 - 3.0 */
433 const ME_Border* borders[4] = { &para->member.para.border.top,
434 &para->member.para.border.left,
435 &para->member.para.border.bottom,
436 &para->member.para.border.right };
437 PARAFORMAT2 *pFmt = &para->member.para.fmt;
438
440 if (pFmt->dxOffset)
441 sprintf(props + strlen(props), "\\trgaph%d", pFmt->dxOffset);
442 if (pFmt->dxStartIndent)
443 sprintf(props + strlen(props), "\\trleft%d", pFmt->dxStartIndent);
444 for (i = 0; i < 4; i++)
445 {
446 if (borders[i]->width)
447 {
448 unsigned int idx;
449 COLORREF crColor = borders[i]->colorRef;
450 sprintf(props + strlen(props), "\\trbrdr%c", sideChar[i]);
451 sprintf(props + strlen(props), "\\brdrs");
452 sprintf(props + strlen(props), "\\brdrw%d", borders[i]->width);
453 if (find_color_in_colortbl( pStream, crColor, &idx ))
454 sprintf(props + strlen(props), "\\brdrcf%u", idx);
455 }
456 }
457 for (i = 0; i < pFmt->cTabCount; i++)
458 {
459 sprintf(props + strlen(props), "\\cellx%d", pFmt->rgxTabs[i] & 0x00FFFFFF);
460 }
461 }
462 if (!ME_StreamOutPrint(pStream, props))
463 return FALSE;
464 props[0] = '\0';
465 return TRUE;
466}
467
469{
470 static const char fmt_label[] = "{\\*\\pn\\pnlvlbody\\pnf%u\\pnindent%d\\pnstart%d%s%s}";
471 static const char fmt_bullet[] = "{\\*\\pn\\pnlvlblt\\pnf%u\\pnindent%d{\\pntxtb\\'b7}}";
472 static const char dec[] = "\\pndec";
473 static const char lcltr[] = "\\pnlcltr";
474 static const char ucltr[] = "\\pnucltr";
475 static const char lcrm[] = "\\pnlcrm";
476 static const char ucrm[] = "\\pnucrm";
477 static const char period[] = "{\\pntxta.}";
478 static const char paren[] = "{\\pntxta)}";
479 static const char parens[] = "{\\pntxtb(}{\\pntxta)}";
480 const char *type, *style = "";
481 unsigned int idx;
482
483 find_font_in_fonttbl( stream, &para->para_num.style->fmt, &idx );
484
485 if (!ME_StreamOutPrint( stream, "{\\pntext\\f%u ", idx )) return FALSE;
486 if (!ME_StreamOutRTFText( stream, para->para_num.text->szData, para->para_num.text->nLen ))
487 return FALSE;
488 if (!ME_StreamOutPrint( stream, "\\tab}" )) return FALSE;
489
490 if (!pn_dest) return TRUE;
491
492 if (para->fmt.wNumbering == PFN_BULLET)
493 {
494 if (!ME_StreamOutPrint( stream, fmt_bullet, idx, para->fmt.wNumberingTab ))
495 return FALSE;
496 }
497 else
498 {
499 switch (para->fmt.wNumbering)
500 {
501 case PFN_ARABIC:
502 default:
503 type = dec;
504 break;
505 case PFN_LCLETTER:
506 type = lcltr;
507 break;
508 case PFN_UCLETTER:
509 type = ucltr;
510 break;
511 case PFN_LCROMAN:
512 type = lcrm;
513 break;
514 case PFN_UCROMAN:
515 type = ucrm;
516 break;
517 }
518 switch (para->fmt.wNumberingStyle & 0xf00)
519 {
520 case PFNS_PERIOD:
521 style = period;
522 break;
523 case PFNS_PAREN:
524 style = paren;
525 break;
526 case PFNS_PARENS:
527 style = parens;
528 break;
529 }
530
531 if (!ME_StreamOutPrint( stream, fmt_label, idx, para->fmt.wNumberingTab,
532 para->fmt.wNumberingStart, type, style ))
533 return FALSE;
534 }
535 return TRUE;
536}
537
538static BOOL
540 ME_DisplayItem *para)
541{
542 PARAFORMAT2 *fmt = &para->member.para.fmt;
543 char props[STREAMOUT_BUFFER_SIZE] = "";
544 int i;
545 ME_Paragraph *prev_para = NULL;
546
547 if (para->member.para.prev_para->type == diParagraph)
548 prev_para = &para->member.para.prev_para->member.para;
549
550 if (!editor->bEmulateVersion10) { /* v4.1 */
551 if (para->member.para.nFlags & MEPF_ROWSTART) {
552 pStream->nNestingLevel++;
553 if (pStream->nNestingLevel == 1) {
554 if (!ME_StreamOutRTFTableProps(editor, pStream, para))
555 return FALSE;
556 }
557 return TRUE;
558 } else if (para->member.para.nFlags & MEPF_ROWEND) {
559 pStream->nNestingLevel--;
560 if (pStream->nNestingLevel >= 1) {
561 if (!ME_StreamOutPrint(pStream, "{\\*\\nesttableprops"))
562 return FALSE;
563 if (!ME_StreamOutRTFTableProps(editor, pStream, para))
564 return FALSE;
565 if (!ME_StreamOutPrint(pStream, "\\nestrow}{\\nonesttables\\par}\r\n"))
566 return FALSE;
567 } else {
568 if (!ME_StreamOutPrint(pStream, "\\row\r\n"))
569 return FALSE;
570 }
571 return TRUE;
572 }
573 } else { /* v1.0 - 3.0 */
574 if (para->member.para.fmt.dwMask & PFM_TABLE &&
576 {
577 if (!ME_StreamOutRTFTableProps(editor, pStream, para))
578 return FALSE;
579 }
580 }
581
582 if (prev_para && !memcmp( fmt, &prev_para->fmt, sizeof(*fmt) ))
583 {
584 if (fmt->wNumbering)
585 return stream_out_para_num( pStream, &para->member.para, FALSE );
586 return TRUE;
587 }
588
589 if (!ME_StreamOutPrint(pStream, "\\pard"))
590 return FALSE;
591
592 if (fmt->wNumbering)
593 if (!stream_out_para_num( pStream, &para->member.para, TRUE )) return FALSE;
594
595 if (!editor->bEmulateVersion10) { /* v4.1 */
596 if (pStream->nNestingLevel > 0)
597 strcat(props, "\\intbl");
598 if (pStream->nNestingLevel > 1)
599 sprintf(props + strlen(props), "\\itap%d", pStream->nNestingLevel);
600 } else { /* v1.0 - 3.0 */
601 if (fmt->dwMask & PFM_TABLE && fmt->wEffects & PFE_TABLE)
602 strcat(props, "\\intbl");
603 }
604
605 /* TODO: PFM_BORDER. M$ does not emit any keywords for these properties, and
606 * when streaming border keywords in, PFM_BORDER is set, but wBorder field is
607 * set very different from the documentation.
608 * (Tested with RichEdit 5.50.25.0601) */
609
610 if (fmt->dwMask & PFM_ALIGNMENT) {
611 switch (fmt->wAlignment) {
612 case PFA_LEFT:
613 /* Default alignment: not emitted */
614 break;
615 case PFA_RIGHT:
616 strcat(props, "\\qr");
617 break;
618 case PFA_CENTER:
619 strcat(props, "\\qc");
620 break;
621 case PFA_JUSTIFY:
622 strcat(props, "\\qj");
623 break;
624 }
625 }
626
627 if (fmt->dwMask & PFM_LINESPACING) {
628 /* FIXME: MSDN says that the bLineSpacingRule field is controlled by the
629 * PFM_SPACEAFTER flag. Is that true? I don't believe so. */
630 switch (fmt->bLineSpacingRule) {
631 case 0: /* Single spacing */
632 strcat(props, "\\sl-240\\slmult1");
633 break;
634 case 1: /* 1.5 spacing */
635 strcat(props, "\\sl-360\\slmult1");
636 break;
637 case 2: /* Double spacing */
638 strcat(props, "\\sl-480\\slmult1");
639 break;
640 case 3:
641 sprintf(props + strlen(props), "\\sl%d\\slmult0", fmt->dyLineSpacing);
642 break;
643 case 4:
644 sprintf(props + strlen(props), "\\sl-%d\\slmult0", fmt->dyLineSpacing);
645 break;
646 case 5:
647 sprintf(props + strlen(props), "\\sl-%d\\slmult1", fmt->dyLineSpacing * 240 / 20);
648 break;
649 }
650 }
651
652 if (fmt->dwMask & PFM_DONOTHYPHEN && fmt->wEffects & PFE_DONOTHYPHEN)
653 strcat(props, "\\hyph0");
654 if (fmt->dwMask & PFM_KEEP && fmt->wEffects & PFE_KEEP)
655 strcat(props, "\\keep");
656 if (fmt->dwMask & PFM_KEEPNEXT && fmt->wEffects & PFE_KEEPNEXT)
657 strcat(props, "\\keepn");
658 if (fmt->dwMask & PFM_NOLINENUMBER && fmt->wEffects & PFE_NOLINENUMBER)
659 strcat(props, "\\noline");
660 if (fmt->dwMask & PFM_NOWIDOWCONTROL && fmt->wEffects & PFE_NOWIDOWCONTROL)
661 strcat(props, "\\nowidctlpar");
662 if (fmt->dwMask & PFM_PAGEBREAKBEFORE && fmt->wEffects & PFE_PAGEBREAKBEFORE)
663 strcat(props, "\\pagebb");
664 if (fmt->dwMask & PFM_RTLPARA && fmt->wEffects & PFE_RTLPARA)
665 strcat(props, "\\rtlpar");
666 if (fmt->dwMask & PFM_SIDEBYSIDE && fmt->wEffects & PFE_SIDEBYSIDE)
667 strcat(props, "\\sbys");
668
669 if (!(editor->bEmulateVersion10 && /* v1.0 - 3.0 */
670 fmt->dwMask & PFM_TABLE && fmt->wEffects & PFE_TABLE))
671 {
672 if (fmt->dxOffset)
673 sprintf(props + strlen(props), "\\li%d", fmt->dxOffset);
674 if (fmt->dxStartIndent)
675 sprintf(props + strlen(props), "\\fi%d", fmt->dxStartIndent);
676 if (fmt->dxRightIndent)
677 sprintf(props + strlen(props), "\\ri%d", fmt->dxRightIndent);
678 if (fmt->dwMask & PFM_TABSTOPS) {
679 static const char * const leader[6] = { "", "\\tldot", "\\tlhyph", "\\tlul", "\\tlth", "\\tleq" };
680
681 for (i = 0; i < fmt->cTabCount; i++) {
682 switch ((fmt->rgxTabs[i] >> 24) & 0xF) {
683 case 1:
684 strcat(props, "\\tqc");
685 break;
686 case 2:
687 strcat(props, "\\tqr");
688 break;
689 case 3:
690 strcat(props, "\\tqdec");
691 break;
692 case 4:
693 /* Word bar tab (vertical bar). Handled below */
694 break;
695 }
696 if (fmt->rgxTabs[i] >> 28 <= 5)
697 strcat(props, leader[fmt->rgxTabs[i] >> 28]);
698 sprintf(props+strlen(props), "\\tx%d", fmt->rgxTabs[i]&0x00FFFFFF);
699 }
700 }
701 }
702 if (fmt->dySpaceAfter)
703 sprintf(props + strlen(props), "\\sa%d", fmt->dySpaceAfter);
704 if (fmt->dySpaceBefore)
705 sprintf(props + strlen(props), "\\sb%d", fmt->dySpaceBefore);
706 if (fmt->sStyle != -1)
707 sprintf(props + strlen(props), "\\s%d", fmt->sStyle);
708
709 if (fmt->dwMask & PFM_SHADING) {
710 static const char * const style[16] = { "", "\\bgdkhoriz", "\\bgdkvert", "\\bgdkfdiag",
711 "\\bgdkbdiag", "\\bgdkcross", "\\bgdkdcross",
712 "\\bghoriz", "\\bgvert", "\\bgfdiag",
713 "\\bgbdiag", "\\bgcross", "\\bgdcross",
714 "", "", "" };
715 if (fmt->wShadingWeight)
716 sprintf(props + strlen(props), "\\shading%d", fmt->wShadingWeight);
717 if (fmt->wShadingStyle & 0xF)
718 strcat(props, style[fmt->wShadingStyle & 0xF]);
719 if ((fmt->wShadingStyle >> 4) & 0xf)
720 sprintf(props + strlen(props), "\\cfpat%d", (fmt->wShadingStyle >> 4) & 0xf);
721 if ((fmt->wShadingStyle >> 8) & 0xf)
722 sprintf(props + strlen(props), "\\cbpat%d", (fmt->wShadingStyle >> 8) & 0xf);
723 }
724 if (*props)
725 strcat(props, " ");
726
727 if (*props && !ME_StreamOutPrint(pStream, props))
728 return FALSE;
729
730 return TRUE;
731}
732
733
734static BOOL
736{
737 char props[STREAMOUT_BUFFER_SIZE] = "";
738 unsigned int i;
739 CHARFORMAT2W *old_fmt = &pStream->cur_fmt;
740 static const struct
741 {
742 DWORD effect;
743 const char *on, *off;
744 } effects[] =
745 {
746 { CFE_ALLCAPS, "\\caps", "\\caps0" },
747 { CFE_BOLD, "\\b", "\\b0" },
748 { CFE_DISABLED, "\\disabled", "\\disabled0" },
749 { CFE_EMBOSS, "\\embo", "\\embo0" },
750 { CFE_HIDDEN, "\\v", "\\v0" },
751 { CFE_IMPRINT, "\\impr", "\\impr0" },
752 { CFE_ITALIC, "\\i", "\\i0" },
753 { CFE_OUTLINE, "\\outl", "\\outl0" },
754 { CFE_PROTECTED, "\\protect", "\\protect0" },
755 { CFE_SHADOW, "\\shad", "\\shad0" },
756 { CFE_SMALLCAPS, "\\scaps", "\\scaps0" },
757 { CFE_STRIKEOUT, "\\strike", "\\strike0" },
758 };
759
760 for (i = 0; i < ARRAY_SIZE( effects ); i++)
761 {
762 if ((old_fmt->dwEffects ^ fmt->dwEffects) & effects[i].effect)
763 strcat( props, fmt->dwEffects & effects[i].effect ? effects[i].on : effects[i].off );
764 }
765
766 if ((old_fmt->dwEffects ^ fmt->dwEffects) & CFE_AUTOBACKCOLOR ||
767 (!(fmt->dwEffects & CFE_AUTOBACKCOLOR) && old_fmt->crBackColor != fmt->crBackColor))
768 {
769 if (fmt->dwEffects & CFE_AUTOBACKCOLOR) i = 0;
770 else find_color_in_colortbl( pStream, fmt->crBackColor, &i );
771 sprintf(props + strlen(props), "\\highlight%u", i);
772 }
773 if ((old_fmt->dwEffects ^ fmt->dwEffects) & CFE_AUTOCOLOR ||
774 (!(fmt->dwEffects & CFE_AUTOCOLOR) && old_fmt->crTextColor != fmt->crTextColor))
775 {
776 if (fmt->dwEffects & CFE_AUTOCOLOR) i = 0;
777 else find_color_in_colortbl( pStream, fmt->crTextColor, &i );
778 sprintf(props + strlen(props), "\\cf%u", i);
779 }
780
781 if (old_fmt->bAnimation != fmt->bAnimation)
782 sprintf(props + strlen(props), "\\animtext%u", fmt->bAnimation);
783 if (old_fmt->wKerning != fmt->wKerning)
784 sprintf(props + strlen(props), "\\kerning%u", fmt->wKerning);
785
786 if (old_fmt->lcid != fmt->lcid)
787 {
788 /* TODO: handle SFF_PLAINRTF */
789 if (LOWORD(fmt->lcid) == 1024)
790 strcat(props, "\\noproof\\lang1024\\langnp1024\\langfe1024\\langfenp1024");
791 else
792 sprintf(props + strlen(props), "\\lang%u", LOWORD(fmt->lcid));
793 }
794
795 if (old_fmt->yOffset != fmt->yOffset)
796 {
797 if (fmt->yOffset >= 0)
798 sprintf(props + strlen(props), "\\up%d", fmt->yOffset);
799 else
800 sprintf(props + strlen(props), "\\dn%d", -fmt->yOffset);
801 }
802 if (old_fmt->yHeight != fmt->yHeight)
803 sprintf(props + strlen(props), "\\fs%d", fmt->yHeight / 10);
804 if (old_fmt->sSpacing != fmt->sSpacing)
805 sprintf(props + strlen(props), "\\expnd%u\\expndtw%u", fmt->sSpacing / 5, fmt->sSpacing);
806 if ((old_fmt->dwEffects ^ fmt->dwEffects) & (CFM_SUBSCRIPT | CFM_SUPERSCRIPT))
807 {
808 if (fmt->dwEffects & CFE_SUBSCRIPT)
809 strcat(props, "\\sub");
810 else if (fmt->dwEffects & CFE_SUPERSCRIPT)
811 strcat(props, "\\super");
812 else
813 strcat(props, "\\nosupersub");
814 }
815 if ((old_fmt->dwEffects ^ fmt->dwEffects) & CFE_UNDERLINE ||
816 old_fmt->bUnderlineType != fmt->bUnderlineType)
817 {
818 BYTE type = (fmt->dwEffects & CFE_UNDERLINE) ? fmt->bUnderlineType : CFU_UNDERLINENONE;
819 switch (type)
820 {
821 case CFU_UNDERLINE:
822 strcat(props, "\\ul");
823 break;
825 strcat(props, "\\uld");
826 break;
828 strcat(props, "\\uldb");
829 break;
831 strcat(props, "\\ulw");
832 break;
833 case CFU_CF1UNDERLINE:
835 default:
836 strcat(props, "\\ulnone");
837 break;
838 }
839 }
840
841 if (wcscmp(old_fmt->szFaceName, fmt->szFaceName) ||
842 old_fmt->bCharSet != fmt->bCharSet)
843 {
844 if (find_font_in_fonttbl( pStream, fmt, &i ))
845 {
846 sprintf(props + strlen(props), "\\f%u", i);
847
848 /* In UTF-8 mode, charsets/codepages are not used */
849 if (pStream->nDefaultCodePage != CP_UTF8)
850 {
851 if (pStream->fonttbl[i].bCharSet == DEFAULT_CHARSET)
852 pStream->nCodePage = pStream->nDefaultCodePage;
853 else
854 pStream->nCodePage = RTFCharSetToCodePage(NULL, pStream->fonttbl[i].bCharSet);
855 }
856 }
857 }
858 if (*props)
859 strcat(props, " ");
860 if (!ME_StreamOutPrint(pStream, props))
861 return FALSE;
862 *old_fmt = *fmt;
863 return TRUE;
864}
865
866
867static BOOL
869{
871 int pos = 0;
872 int fit, nBytes, i;
873
874 if (nChars == -1)
875 nChars = lstrlenW(text);
876
877 while (nChars) {
878 /* In UTF-8 mode, font charsets are not used. */
879 if (pStream->nDefaultCodePage == CP_UTF8) {
880 /* 6 is the maximum character length in UTF-8 */
881 fit = min(nChars, STREAMOUT_BUFFER_SIZE / 6);
882 nBytes = WideCharToMultiByte(CP_UTF8, 0, text, fit, buffer,
884 nChars -= fit;
885 text += fit;
886 for (i = 0; i < nBytes; i++)
887 if (buffer[i] == '{' || buffer[i] == '}' || buffer[i] == '\\') {
888 if (!ME_StreamOutPrint(pStream, "%.*s\\", i - pos, buffer + pos))
889 return FALSE;
890 pos = i;
891 }
892 if (pos < nBytes)
893 if (!ME_StreamOutMove(pStream, buffer + pos, nBytes - pos))
894 return FALSE;
895 pos = 0;
896 } else if (*text < 128) {
897 if (*text == '{' || *text == '}' || *text == '\\')
898 buffer[pos++] = '\\';
899 buffer[pos++] = (char)(*text++);
900 nChars--;
901 } else {
903 char letter[3];
904
905 /* FIXME: In the MS docs for WideCharToMultiByte there is a big list of
906 * codepages including CP_SYMBOL for which the last parameter must be set
907 * to NULL for the function to succeed. But in Wine we need to care only
908 * about CP_SYMBOL */
909 nBytes = WideCharToMultiByte(pStream->nCodePage, 0, text, 1,
910 letter, 3, NULL,
911 (pStream->nCodePage == CP_SYMBOL) ? NULL : &unknown);
912 if (unknown)
913 pos += sprintf(buffer + pos, "\\u%d?", (short)*text);
914 else if ((BYTE)*letter < 128) {
915 if (*letter == '{' || *letter == '}' || *letter == '\\')
916 buffer[pos++] = '\\';
917 buffer[pos++] = *letter;
918 } else {
919 for (i = 0; i < nBytes; i++)
920 pos += sprintf(buffer + pos, "\\'%02x", (BYTE)letter[i]);
921 }
922 text++;
923 nChars--;
924 }
925 if (pos >= STREAMOUT_BUFFER_SIZE - 11) {
926 if (!ME_StreamOutMove(pStream, buffer, pos))
927 return FALSE;
928 pos = 0;
929 }
930 }
931 return ME_StreamOutMove(pStream, buffer, pos);
932}
933
935 ME_Run *run )
936{
938 HRESULT hr;
939 FORMATETC fmt = { CF_ENHMETAFILE, NULL, DVASPECT_CONTENT, -1, TYMED_ENHMF };
940 STGMEDIUM med = { TYMED_NULL };
941 BOOL ret = FALSE;
942 ENHMETAHEADER *emf_bits = NULL;
943 UINT size;
944 SIZE goal, pic;
946
947 hr = IOleObject_QueryInterface( run->reobj->obj.poleobj, &IID_IDataObject, (void **)&data );
948 if (FAILED(hr)) return FALSE;
949
950 ME_InitContext( &c, editor, ITextHost_TxGetDC( editor->texthost ) );
951 hr = IDataObject_QueryGetData( data, &fmt );
952 if (hr != S_OK) goto done;
953
954 hr = IDataObject_GetData( data, &fmt, &med );
955 if (FAILED(hr)) goto done;
956 if (med.tymed != TYMED_ENHMF) goto done;
957
958 size = GetEnhMetaFileBits( med.u.hEnhMetaFile, 0, NULL );
959 if (size < FIELD_OFFSET(ENHMETAHEADER, cbPixelFormat)) goto done;
960
961 emf_bits = HeapAlloc( GetProcessHeap(), 0, size );
962 if (!emf_bits) goto done;
963
964 size = GetEnhMetaFileBits( med.u.hEnhMetaFile, size, (BYTE *)emf_bits );
965 if (size < FIELD_OFFSET(ENHMETAHEADER, cbPixelFormat)) goto done;
966
967 /* size_in_pixels = (frame_size / 100) * szlDevice / szlMillimeters
968 pic = size_in_pixels * 2540 / dpi */
969 pic.cx = MulDiv( emf_bits->rclFrame.right - emf_bits->rclFrame.left, emf_bits->szlDevice.cx * 254,
970 emf_bits->szlMillimeters.cx * c.dpi.cx * 10 );
971 pic.cy = MulDiv( emf_bits->rclFrame.bottom - emf_bits->rclFrame.top, emf_bits->szlDevice.cy * 254,
972 emf_bits->szlMillimeters.cy * c.dpi.cy * 10 );
973
974 /* convert goal size to twips */
975 goal.cx = MulDiv( run->reobj->obj.sizel.cx, 144, 254 );
976 goal.cy = MulDiv( run->reobj->obj.sizel.cy, 144, 254 );
977
978 if (!ME_StreamOutPrint( stream, "{\\*\\shppict{\\pict\\emfblip\\picw%d\\pich%d\\picwgoal%d\\pichgoal%d\n",
979 pic.cx, pic.cy, goal.cx, goal.cy ))
980 goto done;
981
982 if (!ME_StreamOutHexData( stream, (BYTE *)emf_bits, size ))
983 goto done;
984
985 if (!ME_StreamOutPrint( stream, "}}\n" ))
986 goto done;
987
988 ret = TRUE;
989
990done:
992 HeapFree( GetProcessHeap(), 0, emf_bits );
993 ReleaseStgMedium( &med );
994 IDataObject_Release( data );
995 return ret;
996}
997
999 const ME_Cursor *start, int nChars, int dwFormat)
1000{
1002 ME_DisplayItem *prev_para = NULL;
1003 ME_Cursor endCur = cursor;
1004
1005 ME_MoveCursorChars(editor, &endCur, nChars, TRUE);
1006
1007 if (!ME_StreamOutRTFHeader(pStream, dwFormat))
1008 return FALSE;
1009
1010 if (!ME_StreamOutRTFFontAndColorTbl(pStream, cursor.pRun, endCur.pRun))
1011 return FALSE;
1012
1013 /* TODO: stylesheet table */
1014
1015 if (!ME_StreamOutPrint(pStream, "{\\*\\generator Wine Riched20 2.0;}\r\n"))
1016 return FALSE;
1017
1018 /* TODO: information group */
1019
1020 /* TODO: document formatting properties */
1021
1022 /* FIXME: We have only one document section */
1023
1024 /* TODO: section formatting properties */
1025
1026 do {
1027 if (cursor.pPara != prev_para)
1028 {
1029 prev_para = cursor.pPara;
1030 if (!ME_StreamOutRTFParaProps(editor, pStream, cursor.pPara))
1031 return FALSE;
1032 }
1033
1034 if (cursor.pRun == endCur.pRun && !endCur.nOffset)
1035 break;
1036 TRACE("flags %xh\n", cursor.pRun->member.run.nFlags);
1037 /* TODO: emit embedded objects */
1038 if (cursor.pPara->member.para.nFlags & (MEPF_ROWSTART|MEPF_ROWEND))
1039 continue;
1040 if (cursor.pRun->member.run.nFlags & MERF_GRAPHICS) {
1041 if (!stream_out_graphics(editor, pStream, &cursor.pRun->member.run))
1042 return FALSE;
1043 } else if (cursor.pRun->member.run.nFlags & MERF_TAB) {
1044 if (editor->bEmulateVersion10 && /* v1.0 - 3.0 */
1045 cursor.pPara->member.para.fmt.dwMask & PFM_TABLE &&
1046 cursor.pPara->member.para.fmt.wEffects & PFE_TABLE)
1047 {
1048 if (!ME_StreamOutPrint(pStream, "\\cell "))
1049 return FALSE;
1050 } else {
1051 if (!ME_StreamOutPrint(pStream, "\\tab "))
1052 return FALSE;
1053 }
1054 } else if (cursor.pRun->member.run.nFlags & MERF_ENDCELL) {
1055 if (pStream->nNestingLevel > 1) {
1056 if (!ME_StreamOutPrint(pStream, "\\nestcell "))
1057 return FALSE;
1058 } else {
1059 if (!ME_StreamOutPrint(pStream, "\\cell "))
1060 return FALSE;
1061 }
1062 nChars--;
1063 } else if (cursor.pRun->member.run.nFlags & MERF_ENDPARA) {
1064 if (!ME_StreamOutRTFCharProps(pStream, &cursor.pRun->member.run.style->fmt))
1065 return FALSE;
1066
1067 if (cursor.pPara->member.para.fmt.dwMask & PFM_TABLE &&
1068 cursor.pPara->member.para.fmt.wEffects & PFE_TABLE &&
1069 !(cursor.pPara->member.para.nFlags & (MEPF_ROWSTART|MEPF_ROWEND|MEPF_CELL)))
1070 {
1071 if (!ME_StreamOutPrint(pStream, "\\row\r\n"))
1072 return FALSE;
1073 } else {
1074 if (!ME_StreamOutPrint(pStream, "\\par\r\n"))
1075 return FALSE;
1076 }
1077 /* Skip as many characters as required by current line break */
1078 nChars = max(0, nChars - cursor.pRun->member.run.len);
1079 } else if (cursor.pRun->member.run.nFlags & MERF_ENDROW) {
1080 if (!ME_StreamOutPrint(pStream, "\\line\r\n"))
1081 return FALSE;
1082 nChars--;
1083 } else {
1084 int nEnd;
1085
1086 TRACE("style %p\n", cursor.pRun->member.run.style);
1087 if (!ME_StreamOutRTFCharProps(pStream, &cursor.pRun->member.run.style->fmt))
1088 return FALSE;
1089
1090 nEnd = (cursor.pRun == endCur.pRun) ? endCur.nOffset : cursor.pRun->member.run.len;
1091 if (!ME_StreamOutRTFText(pStream, get_text( &cursor.pRun->member.run, cursor.nOffset ),
1092 nEnd - cursor.nOffset))
1093 return FALSE;
1094 cursor.nOffset = 0;
1095 }
1096 } while (cursor.pRun != endCur.pRun && ME_NextRun(&cursor.pPara, &cursor.pRun, TRUE));
1097
1098 if (!ME_StreamOutMove(pStream, "}\0", 2))
1099 return FALSE;
1100 return TRUE;
1101}
1102
1103
1105 const ME_Cursor *start, int nChars, DWORD dwFormat)
1106{
1108 int nLen;
1109 UINT nCodePage = CP_ACP;
1110 char *buffer = NULL;
1111 int nBufLen = 0;
1112 BOOL success = TRUE;
1113
1114 if (!cursor.pRun)
1115 return FALSE;
1116
1117 if (dwFormat & SF_USECODEPAGE)
1118 nCodePage = HIWORD(dwFormat);
1119
1120 /* TODO: Handle SF_TEXTIZED */
1121
1122 while (success && nChars && cursor.pRun) {
1123 nLen = min(nChars, cursor.pRun->member.run.len - cursor.nOffset);
1124
1125 if (!editor->bEmulateVersion10 && cursor.pRun->member.run.nFlags & MERF_ENDPARA)
1126 {
1127 static const WCHAR szEOL[] = { '\r', '\n' };
1128
1129 /* richedit 2.0 - all line breaks are \r\n */
1130 if (dwFormat & SF_UNICODE)
1131 success = ME_StreamOutMove(pStream, (const char *)szEOL, sizeof(szEOL));
1132 else
1133 success = ME_StreamOutMove(pStream, "\r\n", 2);
1134 } else {
1135 if (dwFormat & SF_UNICODE)
1136 success = ME_StreamOutMove(pStream, (const char *)(get_text( &cursor.pRun->member.run, cursor.nOffset )),
1137 sizeof(WCHAR) * nLen);
1138 else {
1139 int nSize;
1140
1141 nSize = WideCharToMultiByte(nCodePage, 0, get_text( &cursor.pRun->member.run, cursor.nOffset ),
1142 nLen, NULL, 0, NULL, NULL);
1143 if (nSize > nBufLen) {
1145 nBufLen = nSize;
1146 }
1147 WideCharToMultiByte(nCodePage, 0, get_text( &cursor.pRun->member.run, cursor.nOffset ),
1148 nLen, buffer, nSize, NULL, NULL);
1149 success = ME_StreamOutMove(pStream, buffer, nSize);
1150 }
1151 }
1152
1153 nChars -= nLen;
1154 cursor.nOffset = 0;
1155 cursor.pRun = ME_FindItemFwd(cursor.pRun, diRun);
1156 }
1157
1159 return success;
1160}
1161
1162
1164 const ME_Cursor *start,
1165 int nChars, EDITSTREAM *stream)
1166{
1167 ME_OutStream *pStream = ME_StreamOutInit(editor, stream);
1168
1169 if (dwFormat & SF_RTF)
1170 ME_StreamOutRTF(editor, pStream, start, nChars, dwFormat);
1171 else if (dwFormat & SF_TEXT || dwFormat & SF_TEXTIZED)
1172 ME_StreamOutText(editor, pStream, start, nChars, dwFormat);
1173 if (!pStream->stream->dwError)
1174 ME_StreamOutFlush(pStream);
1175 return ME_StreamOutFree(pStream);
1176}
1177
1178LRESULT
1180{
1182 int nChars;
1183
1184 if (dwFormat & SFF_SELECTION) {
1185 int nStart, nTo;
1186 start = editor->pCursors[ME_GetSelectionOfs(editor, &nStart, &nTo)];
1187 nChars = nTo - nStart;
1188 } else {
1189 ME_SetCursorToStart(editor, &start);
1190 nChars = ME_GetTextLength(editor);
1191 /* Generate an end-of-paragraph at the end of SCF_ALL RTF output */
1192 if (dwFormat & SF_RTF)
1193 nChars++;
1194 }
1195 return ME_StreamOutRange(editor, dwFormat, &start, nChars, stream);
1196}
ios_base &_STLP_CALL dec(ios_base &__s)
Definition: _ios_base.h:321
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
Arabic default style
Definition: afstyles.h:94
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:71
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define CF_ENHMETAFILE
Definition: constants.h:409
#define ARRAY_SIZE(A)
Definition: main.h:33
CFF_Charset charset
Definition: cffcmap.c:138
#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:1605
#define GetProcessHeap()
Definition: compat.h:736
#define CP_ACP
Definition: compat.h:109
#define HeapAlloc
Definition: compat.h:733
static __inline const char * debugstr_an(const char *s, int n)
Definition: compat.h:55
#define HeapFree(x, y, z)
Definition: compat.h:735
#define WideCharToMultiByte
Definition: compat.h:111
#define lstrlenW
Definition: compat.h:750
BOOL WINAPI GetCPInfoExW(UINT CodePage, DWORD dwFlags, LPCPINFOEXW lpCPInfoEx)
Definition: nls.c:2093
const WCHAR * text
Definition: package.c:1799
void WINAPI ReleaseStgMedium(STGMEDIUM *pmedium)
Definition: ole2.c:2033
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:720
int ME_GetSelectionOfs(ME_TextEditor *editor, int *from, int *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:493
static BOOL find_font_in_fonttbl(ME_OutStream *stream, CHARFORMAT2W *fmt, unsigned int *idx)
Definition: writer.c:257
#define HEX_BYTES_PER_LINE
Definition: writer.c:137
#define STREAMOUT_BUFFER_SIZE
Definition: writer.c:28
static LONG ME_StreamOutFree(ME_OutStream *pStream)
Definition: writer.c:92
static ME_OutStream * ME_StreamOutInit(ME_TextEditor *editor, EDITSTREAM *stream)
Definition: writer.c:55
static BOOL ME_StreamOutRTFParaProps(ME_TextEditor *editor, ME_OutStream *pStream, ME_DisplayItem *para)
Definition: writer.c:539
static void add_color_to_colortbl(ME_OutStream *stream, COLORREF color)
Definition: writer.c:282
static BOOL ME_StreamOutRTFHeader(ME_OutStream *pStream, int dwFormat)
Definition: writer.c:165
LRESULT ME_StreamOutRange(ME_TextEditor *editor, DWORD dwFormat, const ME_Cursor *start, int nChars, EDITSTREAM *stream)
Definition: writer.c:1163
struct tagME_OutStream ME_OutStream
static BOOL find_color_in_colortbl(ME_OutStream *stream, COLORREF color, unsigned int *idx)
Definition: writer.c:297
static BOOL ME_StreamOutRTFCharProps(ME_OutStream *pStream, CHARFORMAT2W *fmt)
Definition: writer.c:735
static BOOL ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream, const ME_Cursor *start, int nChars, DWORD dwFormat)
Definition: writer.c:1104
static BOOL ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream, const ME_Cursor *start, int nChars, int dwFormat)
Definition: writer.c:998
static BOOL ME_StreamOutRTFTableProps(ME_TextEditor *editor, ME_OutStream *pStream, ME_DisplayItem *para)
Definition: writer.c:392
static BOOL ME_StreamOutHexData(ME_OutStream *stream, const BYTE *data, UINT len)
Definition: writer.c:140
static BOOL ME_StreamOutRTFFontAndColorTbl(ME_OutStream *pStream, ME_DisplayItem *pFirstRun, ME_DisplayItem *pLastRun)
Definition: writer.c:315
LRESULT ME_StreamOut(ME_TextEditor *editor, DWORD dwFormat, EDITSTREAM *stream)
Definition: writer.c:1179
static BOOL WINAPIV ME_StreamOutPrint(ME_OutStream *pStream, const char *format,...)
Definition: writer.c:124
static BOOL stream_out_graphics(ME_TextEditor *editor, ME_OutStream *stream, ME_Run *run)
Definition: writer.c:934
static void add_font_to_fonttbl(ME_OutStream *stream, ME_Style *style)
Definition: writer.c:233
#define STREAMOUT_COLORTBL_SIZE
Definition: writer.c:30
static BOOL stream_out_para_num(ME_OutStream *stream, ME_Paragraph *para, BOOL pn_dest)
Definition: writer.c:468
static BOOL ME_StreamOutRTFText(ME_OutStream *pStream, const WCHAR *text, LONG nChars)
Definition: writer.c:868
#define STREAMOUT_FONTTBL_SIZE
Definition: writer.c:29
static BOOL ME_StreamOutFlush(ME_OutStream *pStream)
Definition: writer.c:69
static BOOL ME_StreamOutMove(ME_OutStream *pStream, const char *buffer, int len)
Definition: writer.c:103
unsigned char
Definition: typeof.h:29
#define assert(x)
Definition: debug.h:53
switch(r->id)
Definition: btrfs.c:3046
BOOL ME_NextRun(ME_DisplayItem **para, ME_DisplayItem **run, BOOL all_para) DECLSPEC_HIDDEN
Definition: list.c:71
#define ITextHost_TxGetDC(This)
Definition: editor.h:287
ME_DisplayItem * ME_GetTableRowStart(ME_DisplayItem *para) DECLSPEC_HIDDEN
Definition: table.c:154
static WCHAR * get_text(const ME_Run *run, int offset)
Definition: editor.h:41
ME_DisplayItem * ME_FindItemFwd(ME_DisplayItem *di, ME_DIType nTypeOrClass) DECLSPEC_HIDDEN
Definition: list.c:134
ME_DisplayItem * ME_GetTableRowEnd(ME_DisplayItem *para) DECLSPEC_HIDDEN
Definition: table.c:136
#define MERF_TAB
Definition: editstr.h:107
#define MERF_ENDPARA
Definition: editstr.h:122
#define MERF_ENDCELL
Definition: editstr.h:109
#define MEPF_CELL
Definition: editstr.h:143
#define MERF_GRAPHICS
Definition: editstr.h:105
#define MEPF_ROWSTART
Definition: editstr.h:144
#define MEPF_ROWEND
Definition: editstr.h:145
@ diRun
Definition: editstr.h:87
@ diParagraph
Definition: editstr.h:85
#define MERF_ENDROW
Definition: editstr.h:124
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 GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
GLint GLint GLsizei width
Definition: gl.h:1546
GLsizeiptr size
Definition: glext.h:5919
GLuint buffer
Definition: glext.h:5915
GLuint color
Definition: glext.h:6243
const GLubyte * c
Definition: glext.h:8905
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
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
int hex(char ch)
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
LANGID WINAPI GetUserDefaultLangID(void)
Definition: lang.c:744
USHORT LANGID
Definition: mui.h:9
if(dx< 0)
Definition: linetemp.h:194
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static __ms_va_list valist
Definition: printf.c:66
static ATOM item
Definition: dde.c:856
#define min(a, b)
Definition: monoChain.cc:55
INT WINAPI MulDiv(INT nNumber, INT nNumerator, INT nDenominator)
Definition: muldiv.c:25
unsigned int UINT
Definition: ndis.h:50
const GUID IID_IDataObject
#define LOWORD(l)
Definition: pedump.c:82
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 WINAPIV
Definition: sdbpapi.h:64
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
#define CP_UTF8
Definition: nls.h:20
HRESULT hr
Definition: shlfolder.c:183
#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: parser.c:49
Definition: parse.h:23
RECTL rclFrame
Definition: wingdi.h:2323
SIZEL szlDevice
Definition: wingdi.h:2333
SIZEL szlMillimeters
Definition: wingdi.h:2334
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
struct tagME_DisplayItem * next_cell
Definition: editstr.h:229
ME_BorderRect border
Definition: editstr.h:225
int nOffset
Definition: editstr.h:277
ME_DisplayItem * pRun
Definition: editstr.h:276
union tagME_DisplayItem::@536 member
ME_Cell cell
Definition: editstr.h:261
ME_Paragraph para
Definition: editstr.h:262
EDITSTREAM * stream
Definition: writer.c:34
COLORREF colortbl[STREAMOUT_COLORTBL_SIZE]
Definition: writer.c:41
UINT nFontTblLen
Definition: writer.c:38
UINT written
Definition: writer.c:36
ME_FontTableItem fonttbl[STREAMOUT_FONTTBL_SIZE]
Definition: writer.c:39
CHARFORMAT2W cur_fmt
Definition: writer.c:47
UINT nCodePage
Definition: writer.c:37
UINT nDefaultFont
Definition: writer.c:42
UINT nNestingLevel
Definition: writer.c:46
UINT nColorTblLen
Definition: writer.c:40
char buffer[STREAMOUT_BUFFER_SIZE]
Definition: writer.c:35
UINT nDefaultCodePage
Definition: writer.c:43
struct tagME_DisplayItem * next_para
Definition: editstr.h:217
struct para_num para_num
Definition: editstr.h:215
ME_BorderRect border
Definition: editstr.h:208
struct tagME_DisplayItem * prev_para
Definition: editstr.h:217
PARAFORMAT2 fmt
Definition: editstr.h:204
struct re_object * reobj
Definition: editstr.h:168
ITextHost * texthost
Definition: editstr.h:383
ME_Cursor * pCursors
Definition: editstr.h:387
BOOL bEmulateVersion10
Definition: editstr.h:385
#define max(a, b)
Definition: svc.c:63
#define vsnprintf
Definition: tif_win32.c:406
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
unsigned char * LPBYTE
Definition: typedefs.h:53
#define HIWORD(l)
Definition: typedefs.h:247
static const WCHAR props[]
Definition: wbemdisp.c:288
int ret
#define success(from, fromstr, to, tostr)
*nSize LPSTR _Inout_ LPDWORD nSize
Definition: winbase.h:2084
#define __ms_va_list
Definition: windef.h:456
LONG_PTR LRESULT
Definition: windef.h:209
#define __ms_va_end(list)
Definition: windef.h:458
#define __ms_va_start(list, arg)
Definition: windef.h:457
DWORD COLORREF
Definition: windef.h:300
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:231
UINT WINAPI GetACP(void)
Definition: nls.c:2307
#define CP_SYMBOL
Definition: winnls.h:234
#define CP_MACCP
Definition: winnls.h:232
UINT WINAPI GetOEMCP(void)
Definition: nls.c:2322
__wchar_t WCHAR
Definition: xmlstorage.h:180
unsigned char BYTE
Definition: xxhash.c:193