123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395 |
- using System;
- using System.Collections.Generic;
- using System.IO;
- //using System.Linq;
- using System.Text;
- using System.Drawing.Imaging;
- namespace FastReport.RichTextParser
- {
- #pragma warning disable 1591
- /// <summary>
- /// Save RTF document to text stream
- /// </summary>
- public class RTF_DocumentSaver : IDisposable
- {
- const int PIC_BUFF_SIZE = 512;
- internal const string XCONV = "0123456789ABCDEF";
- private RichDocument doc;
- private ParagraphFormat.HorizontalAlign prev_align = ParagraphFormat.HorizontalAlign.Left;
- RunFormat current_format;
- public ImageFormat imageFormat;
- public bool DomesticCodepage = false;
- public RTF_DocumentSaver(RichDocument doc)
- {
- this.doc = doc;
- imageFormat = ImageFormat.Png;
- }
- private void SaveFontTable(StringBuilder s)
- {
- if (doc.font_list != null)
- {
- s.Append("{\\fonttbl");
- foreach (RFont f in doc.font_list)
- s.AppendFormat("\n{{\\f{0}\\{1}\\fcharset{2} {3};}}", f.font_id, FamilyName(f), f.charset, f.FontName);
- s.Append("}\n");
- }
- }
- private void SaveColorTable(StringBuilder s)
- {
- if (doc.color_list != null)
- {
- s.Append("{\\colortbl;");
- foreach (System.Drawing.Color c in doc.color_list)
- s.AppendFormat("\\red{0}\\green{1}\\blue{2};", c.R, c.G, c.B);
- s.Append("}\n");
- }
- }
- private void SaveStyles(StringBuilder s)
- {
- if (doc.style_list != null)
- {
- ParagraphFormat default_style = new ParagraphFormat();
- s.Append("{\\stylesheet");
- foreach (Style style in doc.style_list)
- {
- s.Append("{\\s").Append(style.styledef);
- SaveParagraphFormat(s, style.paragraph_style, default_style);
- s.Append(" ").Append(style.stylename).Append('}');
- }
- s.Append("}\n");
- }
- }
- internal void SaveHeader(StringBuilder s)
- {
- s.Append("\\rtf1\\ansi");
- if (doc.codepage != 0)
- s.AppendFormat("\\ansicpg{0}", doc.codepage);
- if (doc.default_font != 0)
- s.AppendFormat("\\deff{0}", doc.default_font);
- if (doc.default_lang != 0)
- s.AppendFormat("\\deflang{0}", doc.default_lang);
- SaveFontTable(s);
- SaveColorTable(s);
- SaveStyles(s);
- }
- private string FamilyName(RFont font)
- {
- switch (font.family)
- {
- case RFont.Family.Nil:
- return "fnil";
- case RFont.Family.Rroman:
- return "froman";
- case RFont.Family.Swiss:
- return "fswiss";
- case RFont.Family.Modern:
- return "fmodern";
- case RFont.Family.Script:
- return "fscript";
- case RFont.Family.Decor:
- return "fdecor";
- case RFont.Family.Tech:
- return "ftech";
- case RFont.Family.Bidi:
- return "fbidi";
- default:
- return "froman";
- }
- }
- internal void SaveDocumentBody(StringBuilder s)
- {
- s.AppendFormat("\\paperw{0}\\paperh{1}\\margl{2}\\margt{3}\\margr{4}\\margb{5}\\deftab{6}\n",
- doc.paper_width, doc.paper_height,
- doc.global_margin_left, doc.global_margin_top, doc.global_margin_right, doc.global_margin_bottom,
- doc.default_tab_width);
- if (doc.pages != null)
- foreach (Page p in doc.pages)
- SavePage(s, p, false);
- }
- private void SavePage(StringBuilder s, Page page, bool v)
- {
- if (page.page_width != 0)
- s.AppendFormat(@"\pgwsxn{0}", page.page_width);
- if (page.page_heigh != 0)
- s.AppendFormat(@"\pghsxn{0}", page.page_heigh);
- if(page.margin_left != 0)
- s.AppendFormat(@"\marglsxn{0}", page.margin_left);
- if (page.margin_right != 0)
- s.AppendFormat(@"\margrsxn{0}", page.margin_right);
- if (page.margin_top != 0)
- s.AppendFormat(@"\margtsxn{0}", page.margin_top);
- if (page.margin_bottom != 0)
- s.AppendFormat(@"\margbsxn{0}", page.margin_bottom);
- SaveSequence(s, page.sequence, false);
- }
- private string HorizontalAlignCode(ParagraphFormat.HorizontalAlign align)
- {
- switch (align)
- {
- case ParagraphFormat.HorizontalAlign.Centered: return "\\qc";
- case ParagraphFormat.HorizontalAlign.Left: return "\\ql";
- case ParagraphFormat.HorizontalAlign.Right: return "\\qr";
- case ParagraphFormat.HorizontalAlign.Justified: return "\\qj";
- case ParagraphFormat.HorizontalAlign.Distributed: return "\\qd";
- case ParagraphFormat.HorizontalAlign.Kashida: return "\\qk";
- case ParagraphFormat.HorizontalAlign.Thai: return "\\qt";
- default: return "";
- }
- }
- private string VerticalAlignCode(Column.VertAlign valign)
- {
- switch (valign)
- {
- case Column.VertAlign.Top: return "\\clvertalt";
- case Column.VertAlign.Center: return "\\clvertalc";
- case Column.VertAlign.Bottom: return "\\clvertalb";
- default: return "";
- }
- }
- private void SaveParagraphFormat(StringBuilder sb, ParagraphFormat format, ParagraphFormat prev_format)
- {
- if (format.align != prev_format.align)
- sb.Append(HorizontalAlignCode(format.align));
- if (format.line_spacing != prev_format.line_spacing)
- sb.Append("\\sl").Append(format.line_spacing);
- if (format.space_before != prev_format.space_before)
- sb.Append("\\sb").Append(format.space_before);
- if (format.space_after != prev_format.space_after)
- sb.Append("\\sa").Append(format.space_after);
- if (format.left_indent != prev_format.left_indent)
- sb.Append("\\li").Append(format.left_indent);
- if (format.right_indent != prev_format.right_indent)
- sb.Append("\\fi").Append(format.right_indent);
- if (format.first_line_indent != prev_format.first_line_indent)
- sb.Append("\\fi").Append(format.first_line_indent);
- if (format.lnspcmult != prev_format.lnspcmult)
- sb.Append("\\slmult").Append(format.lnspcmult);
- }
- private void SavePargraph(StringBuilder sb, Paragraph par, bool InTable)
- {
- if (par.runs.Count == 0)
- {
- if (!InTable)
- sb.Append("\\pard\\par\n");
- else
- sb.Append("\\pard\\intbl\\cell\n");
- }
- else
- {
- if (InTable)
- sb.Append("\\intbl\n");
- if (par.format.align != prev_align)
- {
- sb.AppendFormat("{0} ", HorizontalAlignCode(par.format.align));
- prev_align = par.format.align;
- }
- sb.Append("\\sl").Append(par.format.line_spacing);
- sb.Append("\\sb").Append(par.format.space_before);
- sb.Append("\\sa").Append(par.format.space_after);
- sb.Append("\\li").Append(par.format.left_indent);
- sb.Append("\\fi").Append(par.format.right_indent);
- sb.Append("\\fi").Append(par.format.first_line_indent);
- sb.Append("\\slmult").Append(par.format.lnspcmult);
- foreach (Run r in par.runs)
- {
- RunFormat fmt = r.format;
- if (current_format.bold != fmt.bold)
- {
- sb.Append(fmt.bold ? "\\b" : "\\b0");
- current_format.bold = fmt.bold;
- }
- if (current_format.underline != fmt.underline)
- {
- sb.Append(fmt.underline ? "\\ul" : "\\ulnone");
- current_format.underline = fmt.underline;
- }
- if (current_format.italic != fmt.italic)
- {
- sb.Append(fmt.italic ? "\\i" : "\\i0");
- current_format.italic = fmt.italic;
- }
- int curr_color_idx = doc.color_list.IndexOf(current_format.color);
- int fmt_color_idx = doc.color_list.IndexOf(fmt.color);
- if(fmt_color_idx == -1)
- {
- fmt_color_idx = doc.color_list.Count;
- doc.color_list.Add(fmt.color);
- }
- if (curr_color_idx != fmt_color_idx)
- {
- sb.AppendFormat("\\cf{0}", fmt_color_idx);
- current_format.color = fmt.color;
- }
- if (current_format.font_size != fmt.font_size)
- {
- sb.AppendFormat("\\fs{0}", fmt.font_size);
- current_format.font_size = fmt.font_size;
- }
- if (current_format.font_idx != fmt.font_idx)
- {
- sb.AppendFormat("\\f{0}", fmt.font_idx);
- current_format.font_idx = fmt.font_idx;
- }
- sb.Append(" ");
- if (r.text.Length == 0)
- sb.Append("\\tab ");
- else
- #if true
- foreach (char ch in r.text)
- {
- if (ch < 128 || DomesticCodepage)
- sb.Append(ch);
- else
- {
- sb.Append("\\u" + Convert.ToUInt32(ch) + "?");
- }
- }
- #else
- s.Append(r.text);
- #endif
- }
- if (!InTable)
- sb.Append("\\par\n");
- else
- sb.Append("\\cell\n");
- }
- }
- private void SavePicture(StringBuilder CellsStream, Picture pic, bool InTable)
- {
- CellsStream.Append("\\sb0\\li0\\sl0\\slmult0\\qc\\clvertalc {");
- float dx = (int)pic.width;
- float dy = (int)pic.height;
- CellsStream.Append("\\pict\\picw").Append(dx.ToString());
- CellsStream.Append("\\pich").Append(dy.ToString());
- CellsStream.Append("\\picwgoal").Append(pic.desired_width);
- CellsStream.Append("\\pichgoal").Append(pic.desired_height);
- CellsStream.Append("\\picscalex").Append(pic.scalex);
- CellsStream.Append("\\picscaley").Append(pic.scaley);
- if (imageFormat == System.Drawing.Imaging.ImageFormat.Jpeg)
- {
- CellsStream.Append("\\jpegblip\r\n");
- }
- else
- {
- CellsStream.Append("\\pngblip\r\n");
- imageFormat = System.Drawing.Imaging.ImageFormat.Png;
- }
- int n;
- byte[] picbuff = new Byte[PIC_BUFF_SIZE];
- MemoryStream pic_stream = new MemoryStream();
- pic.image.Save(pic_stream, imageFormat);
- pic_stream.Position = 0;
- do
- {
- n = pic_stream.Read(picbuff, 0, PIC_BUFF_SIZE);
- for (int z = 0; z < n; z++)
- {
- CellsStream.Append(XCONV[picbuff[z] >> 4]);
- CellsStream.Append(XCONV[picbuff[z] & 0xF]);
- }
- CellsStream.Append("\r\n");
- }
- while (n == PIC_BUFF_SIZE);
- CellsStream.Append("}");
- }
- private void SaveTable(StringBuilder s, Table tbl, bool InTable)
- {
- s.Append("\\trowd");
- foreach (Column col in tbl.columns)
- SaveColumn(s, col);
- foreach (TableRow row in tbl.rows)
- SaveRow(s, row);
- }
- private void SaveColumn(StringBuilder s, Column col)
- {
- // "clcbpat" - background color
- s.AppendFormat("{0}\\cellx{1}", VerticalAlignCode(col.valign), col.Width);
- }
- private void SaveRow(StringBuilder s, TableRow row)
- {
- s.AppendFormat("\\trgaph{0}\\trrh{1}\\trpaddl{2}\\trpaddr{3}",
- row.trgaph, row.height, row.default_pad_left, row.default_pad_right);
- foreach (RichObjectSequence seq in row.cells)
- {
- SaveSequence(s, seq, true);
- s.AppendLine("\\cell");
- }
- s.Append("\\row");
- }
- private void SaveSequence(StringBuilder s, RichObjectSequence seq, bool InTable)
- {
- foreach (RichObject robj in seq.objects)
- {
- switch (robj.type)
- {
- case RichObject.Type.Paragraph:
- SavePargraph(s, robj.pargraph, InTable);
- break;
- case RichObject.Type.Picture:
- SavePicture(s, robj.picture, InTable);
- break;
- case RichObject.Type.Table:
- SaveTable(s, robj.table, InTable);
- break;
- }
- }
- }
- public void Save(Stream stream)
- {
- StringBuilder s = new StringBuilder();
- stream.WriteByte((byte)'{');
- SaveHeader(s);
- SaveDocumentBody(s);
- ExportUtils.Write(stream, s.ToString());
- stream.WriteByte((byte)'}');
- }
- public string RichText
- {
- get
- {
- StringBuilder s = new StringBuilder();
- s.Append('{');
- SaveHeader(s);
- SaveDocumentBody(s);
- s.Append('}');
- return s.ToString();
- }
- }
- public void Dispose()
- {
- // Perhaps that everything clean
- }
- }
- #pragma warning restore 1591
- }
|