ReactOS  0.4.14-dev-614-gbfd8a84
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 
32 typedef 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 */
48 } ME_OutStream;
49 
50 static BOOL
51 ME_StreamOutRTFText(ME_OutStream *pStream, const WCHAR *text, LONG nChars);
52 
53 
54 static 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 
68 static 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 
91 static 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 
102 static BOOL
103 ME_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 
123 static BOOL WINAPIV
124 ME_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 
139 static 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 
164 static BOOL
165 ME_StreamOutRTFHeader(ME_OutStream *pStream, int dwFormat)
166 {
167  const char *cCharSet = NULL;
168  UINT nCodePage;
169  LANGID language;
170  BOOL success;
171 
172  if (dwFormat & SF_USECODEPAGE) {
173  CPINFOEXW info;
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 
314 static 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 
391 static 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 */
403  PARAFORMAT2 *pFmt = &ME_GetTableRowEnd(para)->member.para.fmt;
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 
538 static 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 &&
575  para->member.para.fmt.wEffects & PFE_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 
734 static 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;
824  case CFU_UNDERLINEDOTTED:
825  strcat(props, "\\uld");
826  break;
827  case CFU_UNDERLINEDOUBLE:
828  strcat(props, "\\uldb");
829  break;
830  case CFU_UNDERLINEWORD:
831  strcat(props, "\\ulw");
832  break;
833  case CFU_CF1UNDERLINE:
834  case CFU_UNDERLINENONE:
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 
867 static BOOL
868 ME_StreamOutRTFText(ME_OutStream *pStream, const WCHAR *text, LONG nChars)
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 {
902  BOOL unknown = FALSE;
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 {
937  IDataObject *data;
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;
945  ME_Context c;
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 
990 done:
991  ME_DestroyContext( &c );
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 {
1001  ME_Cursor cursor = *start;
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 {
1107  ME_Cursor cursor = *start;
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 
1158  heap_free(buffer);
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 
1178 LRESULT
1180 {
1181  ME_Cursor start;
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 }
ME_DisplayItem * ME_GetTableRowStart(ME_DisplayItem *para) DECLSPEC_HIDDEN
Definition: table.c:154
#define PFA_RIGHT
Definition: richedit.h:922
#define MEPF_ROWEND
Definition: editstr.h:149
#define PFM_RTLPARA
Definition: richedit.h:856
#define PFN_BULLET
Definition: richedit.h:905
static BOOL ME_StreamOutText(ME_TextEditor *editor, ME_OutStream *pStream, const ME_Cursor *start, int nChars, DWORD dwFormat)
Definition: writer.c:1104
#define CFE_AUTOCOLOR
Definition: richedit.h:414
#define vsnprintf
Definition: tif_win32.c:406
#define STREAMOUT_COLORTBL_SIZE
Definition: writer.c:30
GLint GLint GLsizei width
Definition: gl.h:1546
static BOOL ME_StreamOutHexData(ME_OutStream *stream, const BYTE *data, UINT len)
Definition: writer.c:140
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define max(a, b)
Definition: svc.c:63
static BOOL ME_StreamOutRTFText(ME_OutStream *pStream, const WCHAR *text, LONG nChars)
Definition: writer.c:868
ME_Paragraph para
Definition: editstr.h:266
#define TRUE
Definition: types.h:120
#define CFU_UNDERLINEWORD
Definition: richedit.h:429
#define PFN_UCLETTER
Definition: richedit.h:908
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ME_Border top
Definition: editstr.h:192
CFF_Charset charset
Definition: cffcmap.c:138
static BOOL find_color_in_colortbl(ME_OutStream *stream, COLORREF color, unsigned int *idx)
Definition: writer.c:297
#define WideCharToMultiByte
Definition: compat.h:101
static static const char __ms_va_list
Definition: printf.c:76
#define CF_ENHMETAFILE
Definition: constants.h:409
HRESULT hr
Definition: shlfolder.c:183
#define CFM_SUBSCRIPT
Definition: richedit.h:348
#define CFE_UNDERLINE
Definition: richedit.h:408
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
BYTE bUnderlineType
Definition: richedit.h:321
BOOL ME_NextRun(ME_DisplayItem **para, ME_DisplayItem **run, BOOL all_para) DECLSPEC_HIDDEN
Definition: list.c:71
#define PFM_SIDEBYSIDE
Definition: richedit.h:863
void WINAPI ReleaseStgMedium(STGMEDIUM *pmedium)
Definition: ole2.c:2033
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
SHORT sSpacing
Definition: richedit.h:315
WORD wNumberingStart
Definition: richedit.h:680
#define SF_RTF
Definition: richedit.h:721
EDITSTREAM * stream
Definition: writer.c:34
#define PFM_TABSTOPS
Definition: richedit.h:842
const WCHAR * text
Definition: package.c:1827
#define CP_ACP
Definition: compat.h:99
struct re_object * reobj
Definition: editstr.h:172
#define CFU_UNDERLINE
Definition: richedit.h:428
*nSize LPSTR _Inout_ LPDWORD nSize
Definition: winbase.h:2031
#define CFM_FACE
Definition: richedit.h:360
#define MERF_GRAPHICS
Definition: editstr.h:109
#define CFE_SUBSCRIPT
Definition: richedit.h:412
const char * fmt
Definition: wsprintf.c:30
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
#define PFM_ALIGNMENT
Definition: richedit.h:841
#define CFM_SUPERSCRIPT
Definition: richedit.h:349
#define assert(x)
Definition: debug.h:53
COLORREF colortbl[STREAMOUT_COLORTBL_SIZE]
Definition: writer.c:41
GLuint buffer
Definition: glext.h:5915
LRESULT ME_StreamOut(ME_TextEditor *editor, DWORD dwFormat, EDITSTREAM *stream)
Definition: writer.c:1179
int ME_GetSelectionOfs(ME_TextEditor *editor, int *from, int *to)
Definition: caret.c:42
const GUID IID_IDataObject
ios_base &_STLP_CALL dec(ios_base &__s)
Definition: _ios_base.h:321
struct tagME_DisplayItem * prev_para
Definition: editstr.h:221
SHORT cTabCount
Definition: richedit.h:674
WORD LANGID
Definition: typedefs.h:79
ME_DisplayItem * ME_GetTableRowEnd(ME_DisplayItem *para) DECLSPEC_HIDDEN
Definition: table.c:136
COLORREF crBackColor
Definition: richedit.h:316
#define PFNS_PAREN
Definition: richedit.h:913
UINT nDefaultCodePage
Definition: writer.c:43
UINT nColorTblLen
Definition: writer.c:40
WORD face[3]
Definition: mesh.c:4747
#define PFM_LINESPACING
Definition: richedit.h:849
#define DEFAULT_CHARSET
Definition: wingdi.h:383
static const char hex[16]
Definition: profile.c:123
#define lstrlenW
Definition: compat.h:415
#define STREAMOUT_BUFFER_SIZE
Definition: writer.c:28
WORD wKerning
Definition: richedit.h:320
#define CP_SYMBOL
Definition: winnls.h:231
#define PFE_NOLINENUMBER
Definition: richedit.h:936
static BOOL WINAPIV ME_StreamOutPrint(ME_OutStream *pStream, const char *format,...)
Definition: writer.c:124
#define CFE_SHADOW
Definition: richedit.h:420
#define PFE_RTLPARA
Definition: richedit.h:932
WORD wNumberingStyle
Definition: richedit.h:680
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:70
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl.h:1546
#define PFE_DONOTHYPHEN
Definition: richedit.h:938
WINE_DEFAULT_DEBUG_CHANNEL(richedit)
CHARFORMAT2W cur_fmt
Definition: writer.c:47
struct _test_info info[]
Definition: SetCursorPos.c:19
int RTFCharSetToCodePage(RTF_Info *info, int charset)
Definition: reader.c:493
#define CFE_BOLD
Definition: richedit.h:406
LONG rgxTabs[MAX_TAB_STOPS]
Definition: richedit.h:675
#define MERF_TAB
Definition: editstr.h:111
#define sprintf(buf, format,...)
Definition: sprintf.c:55
WORD wNumbering
Definition: richedit.h:668
static BOOL ME_StreamOutRTFParaProps(ME_TextEditor *editor, ME_OutStream *pStream, ME_DisplayItem *para)
Definition: writer.c:539
#define CFU_UNDERLINENONE
Definition: richedit.h:427
UINT WINAPI GetEnhMetaFileBits(_In_ HENHMETAFILE hEMF, _In_ UINT nSize, _Out_writes_bytes_opt_(nSize) LPBYTE lpData)
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
WORD wNumberingTab
Definition: richedit.h:680
#define PFNS_PERIOD
Definition: richedit.h:915
unsigned char * LPBYTE
Definition: typedefs.h:52
UINT written
Definition: writer.c:36
#define CP_UTF8
Definition: nls.h:20
#define SFF_SELECTION
Definition: richedit.h:979
unsigned int BOOL
Definition: ntddk_ex.h:94
long LONG
Definition: pedump.c:60
GLuint color
Definition: glext.h:6243
#define CFE_PROTECTED
Definition: richedit.h:410
#define MEPF_CELL
Definition: editstr.h:147
static BOOL ME_StreamOutFlush(ME_OutStream *pStream)
Definition: writer.c:69
unsigned int idx
Definition: utils.c:41
static BOOL stream_out_para_num(ME_OutStream *stream, ME_Paragraph *para, BOOL pn_dest)
Definition: writer.c:468
#define CFE_IMPRINT
Definition: richedit.h:422
#define STREAMOUT_FONTTBL_SIZE
Definition: writer.c:29
#define MERF_ENDPARA
Definition: editstr.h:126
LONG dxStartIndent
Definition: richedit.h:670
static void add_color_to_colortbl(ME_OutStream *stream, COLORREF color)
Definition: writer.c:282
#define CFM_COLOR
Definition: richedit.h:361
smooth NULL
Definition: ftsmooth.c:416
DWORD dwEffects
Definition: richedit.h:307
Definition: editstr.h:91
unsigned char
Definition: typeof.h:29
#define PFE_PAGEBREAKBEFORE
Definition: richedit.h:935
LONG cx
Definition: windef.h:334
UINT WINAPI GetACP(VOID)
Definition: nls.c:2180
void ME_InitContext(ME_Context *c, ME_TextEditor *editor, HDC hDC)
Definition: context.c:23
Definition: parser.c:48
switch(r->id)
Definition: btrfs.c:2904
#define CFE_SUPERSCRIPT
Definition: richedit.h:413
#define PFE_TABLE
Definition: richedit.h:944
static BOOL stream_out_graphics(ME_TextEditor *editor, ME_OutStream *stream, ME_Run *run)
Definition: writer.c:934
DWORD dwMask
Definition: richedit.h:667
UINT nFontTblLen
Definition: writer.c:38
#define ITextHost_TxGetDC(This)
Definition: editor.h:287
#define CFU_UNDERLINEDOUBLE
Definition: richedit.h:430
#define CFE_AUTOBACKCOLOR
Definition: richedit.h:425
char buffer[STREAMOUT_BUFFER_SIZE]
Definition: writer.c:35
void ME_SetCursorToStart(ME_TextEditor *editor, ME_Cursor *cursor)
Definition: caret.c:27
ME_BorderRect border
Definition: editstr.h:212
#define SF_TEXT
Definition: richedit.h:720
#define TRACE(s)
Definition: solgame.cpp:4
GLsizeiptr size
Definition: glext.h:5919
#define CFU_CF1UNDERLINE
Definition: richedit.h:447
#define GetProcessHeap()
Definition: compat.h:403
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
if(!(yy_init))
Definition: macro.lex.yy.c:714
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:77
DWORD COLORREF
Definition: windef.h:300
#define PFA_CENTER
Definition: richedit.h:923
const GLubyte * c
Definition: glext.h:8905
unsigned long DWORD
Definition: ntddk_ex.h:95
#define CFE_EMBOSS
Definition: richedit.h:421
#define success(from, fromstr, to, tostr)
#define PFN_LCROMAN
Definition: richedit.h:909
#define PFM_NOWIDOWCONTROL
Definition: richedit.h:861
Definition: id3.c:18
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
void ME_DestroyContext(ME_Context *c)
Definition: context.c:44
struct tagME_OutStream ME_OutStream
static BOOL ME_StreamOutRTFCharProps(ME_OutStream *pStream, CHARFORMAT2W *fmt)
Definition: writer.c:735
ME_BorderRect border
Definition: editstr.h:229
WCHAR szFaceName[LF_FACESIZE]
Definition: richedit.h:313
#define MEPF_ROWSTART
Definition: editstr.h:148
int ret
static ME_OutStream * ME_StreamOutInit(ME_TextEditor *editor, EDITSTREAM *stream)
Definition: writer.c:55
#define PFNS_PARENS
Definition: richedit.h:914
ITextHost * texthost
Definition: editstr.h:387
#define PFM_TABLE
Definition: richedit.h:870
#define PFM_SHADING
Definition: richedit.h:852
Definition: parse.h:22
int nRightBoundary
Definition: editstr.h:228
static __inline const char * debugstr_an(const char *s, int n)
Definition: compat.h:47
#define CFE_ITALIC
Definition: richedit.h:407
GLuint GLuint stream
Definition: glext.h:7522
int nOffset
Definition: editstr.h:281
#define MERF_ENDCELL
Definition: editstr.h:113
#define PFN_UCROMAN
Definition: richedit.h:910
#define SF_TEXTIZED
Definition: richedit.h:723
GLenum GLsizei len
Definition: glext.h:6722
#define CFE_ALLCAPS
Definition: richedit.h:417
unsigned char BYTE
Definition: mem.h:68
#define PFM_KEEPNEXT
Definition: richedit.h:858
static WCHAR * get_text(const ME_Run *run, int offset)
Definition: editor.h:41
UINT nNestingLevel
Definition: writer.c:46
#define PFE_KEEP
Definition: richedit.h:933
static BOOL ME_StreamOutRTFFontAndColorTbl(ME_OutStream *pStream, ME_DisplayItem *pFirstRun, ME_DisplayItem *pLastRun)
Definition: writer.c:315
static BOOL ME_StreamOutMove(ME_OutStream *pStream, const char *buffer, int len)
Definition: writer.c:103
static BOOL ME_StreamOutRTFHeader(ME_OutStream *pStream, int dwFormat)
Definition: writer.c:165
#define PFN_ARABIC
Definition: richedit.h:906
ME_Cell cell
Definition: editstr.h:265
static LONG ME_StreamOutFree(ME_OutStream *pStream)
Definition: writer.c:92
COLORREF crTextColor
Definition: richedit.h:310
#define WINAPIV
Definition: sdbpapi.h:64
#define PFM_DONOTHYPHEN
Definition: richedit.h:862
#define PFM_NOLINENUMBER
Definition: richedit.h:860
#define CFE_OUTLINE
Definition: richedit.h:419
WORD wEffects
Definition: richedit.h:669
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
COLORREF colorRef
Definition: editstr.h:187
ME_Border right
Definition: editstr.h:195
#define S_OK
Definition: intsafe.h:59
ME_Border bottom
Definition: editstr.h:194
#define CFE_DISABLED
Definition: richedit.h:423
static ATOM item
Definition: dde.c:856
const char cursor[]
Definition: icontest.c:13
BOOL bEmulateVersion10
Definition: editstr.h:389
ME_Cursor * pCursors
Definition: editstr.h:391
PARAFORMAT2 fmt
Definition: editstr.h:208
struct para_num para_num
Definition: editstr.h:219
GLuint start
Definition: gl.h:1545
#define ARRAY_SIZE(a)
Definition: main.h:24
static void add_font_to_fonttbl(ME_OutStream *stream, ME_Style *style)
Definition: writer.c:233
#define MERF_ENDROW
Definition: editstr.h:128
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
BYTE bCharSet
Definition: richedit.h:311
DWORD dwError
Definition: richedit.h:523
UINT nCodePage
Definition: writer.c:37
ME_FontTableItem fonttbl[STREAMOUT_FONTTBL_SIZE]
Definition: writer.c:39
#define min(a, b)
Definition: monoChain.cc:55
struct tagME_DisplayItem * next_para
Definition: editstr.h:221
unsigned int UINT
Definition: ndis.h:50
#define __ms_va_end(list)
Definition: windef.h:458
ME_DisplayItem * pRun
Definition: editstr.h:280
#define CFU_UNDERLINEDOTTED
Definition: richedit.h:431
int ME_MoveCursorChars(ME_TextEditor *editor, ME_Cursor *cursor, int nRelOfs, BOOL final_eop)
Definition: caret.c:675
#define HEX_BYTES_PER_LINE
Definition: writer.c:137
#define PFA_JUSTIFY
Definition: richedit.h:924
static BOOL ME_StreamOutRTF(ME_TextEditor *editor, ME_OutStream *pStream, const ME_Cursor *start, int nChars, int dwFormat)
Definition: writer.c:998
BYTE bAnimation
Definition: richedit.h:322
#define CFM_BACKCOLOR
Definition: richedit.h:357
#define PFM_KEEP
Definition: richedit.h:857
#define CFE_STRIKEOUT
Definition: richedit.h:409
struct tagME_DisplayItem * next_cell
Definition: editstr.h:233
#define PFE_NOWIDOWCONTROL
Definition: richedit.h:937
ME_Border left
Definition: editstr.h:193
#define __ms_va_start(list, arg)
Definition: windef.h:457
static const WCHAR props[]
Definition: wbemdisp.c:288
#define PFA_LEFT
Definition: richedit.h:921
#define PFE_KEEPNEXT
Definition: richedit.h:934
#define c
Definition: ke_i.h:80
#define HIWORD(l)
Definition: typedefs.h:246
ME_DisplayItem * ME_FindItemFwd(ME_DisplayItem *di, ME_DIType nTypeOrClass) DECLSPEC_HIDDEN
Definition: list.c:134
BOOL WINAPI GetCPInfoExW(UINT CodePage, DWORD dwFlags, LPCPINFOEXW lpCPInfoEx)
Definition: nls.c:1969
static BOOL ME_StreamOutRTFTableProps(ME_TextEditor *editor, ME_OutStream *pStream, ME_DisplayItem *para)
Definition: writer.c:392
#define CFE_HIDDEN
Definition: richedit.h:418
LANGID WINAPI GetUserDefaultLangID(void)
Definition: lang.c:734
static __ms_va_list valist
Definition: printf.c:64
#define PFN_LCLETTER
Definition: richedit.h:907
LONG_PTR LRESULT
Definition: windef.h:209
UINT nDefaultFont
Definition: writer.c:42
LONG dxOffset
Definition: richedit.h:672
Arabic default style
Definition: afstyles.h:93
LONG yHeight
Definition: richedit.h:308
LONG cy
Definition: windef.h:335
#define CFE_SMALLCAPS
Definition: richedit.h:416
#define LOWORD(l)
Definition: pedump.c:82
Definition: dsound.c:943
#define CP_OEMCP
Definition: winnls.h:228
#define HeapFree(x, y, z)
Definition: compat.h:402
#define MulDiv(x, y, z)
Definition: gdifloat.h:86
#define CFM_CHARSET
Definition: richedit.h:358
static BOOL find_font_in_fonttbl(ME_OutStream *stream, CHARFORMAT2W *fmt, unsigned int *idx)
Definition: writer.c:257
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
int ME_GetTextLength(ME_TextEditor *editor)
Definition: caret.c:83
union tagME_DisplayItem::@521 member
#define PFE_SIDEBYSIDE
Definition: richedit.h:939
#define PFM_PAGEBREAKBEFORE
Definition: richedit.h:859
#define CP_MACCP
Definition: winnls.h:229
static BOOL heap_free(void *mem)
Definition: appwiz.h:75
LONG yOffset
Definition: richedit.h:309
LRESULT ME_StreamOutRange(ME_TextEditor *editor, DWORD dwFormat, const ME_Cursor *start, int nChars, EDITSTREAM *stream)
Definition: writer.c:1163
off
Definition: i386-dis.c:3909
UINT WINAPI GetOEMCP(VOID)
Definition: nls.c:2195
#define SF_UNICODE
Definition: richedit.h:724
#define SF_USECODEPAGE
Definition: richedit.h:725