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