using System; using System.Collections.Generic; using System.Drawing; using System.IO; using System.Text; using FastReport.Table; using FastReport.Utils; namespace FastReport.Export.LaTeX { /// /// Represents the LaTeX export filter. /// public partial class LaTeXExport : ExportBase { const float PT_MM = 2.834645669291f; const float PT_INCH = 72; const float PT_PX = 72f / 96f; private float leftMargin = 0; private float topMargin = 0; private float leftStartPos = 0; private float topStartPos = 0; #region Private Methods private void Write(Stream stream, string value) { byte[] buf = Encoding.UTF8.GetBytes(value); stream.Write(buf, 0, buf.Length); } private void WriteLn(Stream stream, string value) { byte[] buf = Encoding.UTF8.GetBytes(value); stream.Write(buf, 0, buf.Length); stream.WriteByte(13); stream.WriteByte(10); } #endregion #region Protected Methods /// protected override void Start() { base.Start(); WriteLn(Stream, @"\documentclass{report}"); WriteLn(Stream, @"\usepackage{xltxtra}"); WriteLn(Stream, @"\usepackage{vmargin}"); WriteLn(Stream, @"\usepackage[absolute,overlay]{textpos}"); WriteLn(Stream, @"\usepackage{ragged2e}"); WriteLn(Stream, @"\author {" + PrepareString(Report.ReportInfo.Author) + "}"); WriteLn(Stream, @"\title {" + PrepareString(Report.ReportInfo.Name) + "}"); WriteLn(Stream, @"\date {\today}"); WriteLn(Stream, @"\newcommand{\textout}[3]{\setlength{\parindent}{0mm}{\fontspec{#1}{\fontsize{#2}{12}\selectfont {#3}}}}"); WriteLn(Stream, @"\newcommand{\text}[6]{"); WriteLn(Stream, @"\raggedright\begin{textblock*}{#1}(#2,#3)"); WriteLn(Stream, @"{\textout{#4}{#5}{#6}}"); WriteLn(Stream, @"\end{textblock*}}"); WriteLn(Stream, @"\newcommand{\textright}[6]{"); WriteLn(Stream, @"\raggedleft\begin{textblock*}{#1}(#2,#3)"); WriteLn(Stream, @"{\textout{#4}{#5}{#6}}"); WriteLn(Stream, @"\end{textblock*}}"); WriteLn(Stream, @"\newcommand{\textcenter}[6]{"); WriteLn(Stream, @"\centering\begin{textblock*}{#1}(#2,#3)"); WriteLn(Stream, @"{\textout{#4}{#5}{#6}}"); WriteLn(Stream, @"\end{textblock*}}"); WriteLn(Stream, @"\newcommand{\textjustify}[6]{"); WriteLn(Stream, @"\justify\begin{textblock*}{#1}(#2,#3)"); WriteLn(Stream, @"{\textout{#4}{#5}{#6}}"); WriteLn(Stream, @"\end{textblock*}}"); WriteLn(Stream, @"\begin{document}"); } /// protected override void Finish() { WriteLn(Stream, @"\end{document}"); } /// protected override string GetFileFilter() { return new MyRes("FileFilters").Get("LaTeXFile"); } /// protected override void ExportPageBegin(ReportPage page) { base.ExportPageBegin(page); leftMargin = page.LeftMargin * PT_MM; topMargin = page.TopMargin * PT_MM; leftStartPos = leftMargin + PT_INCH; topStartPos = topMargin + PT_INCH; WriteLn(Stream, @"\setpapersize{custom}{" + page.PaperWidth.ToString() + "mm}{" + page.PaperHeight.ToString() + "mm}"); WriteLn(Stream, @"\setmarginsrb{" + Math.Round(leftMargin, 2).ToString("R") + "pt}{" + Math.Round(topMargin, 2).ToString("R") + "pt}{" + Math.Round(page.RightMargin * PT_MM, 2).ToString("R") + "pt}{" + Math.Round(page.BottomMargin * PT_MM, 2).ToString("R") + "pt}{0pt}{0pt}{0pt}{0pt}"); WriteLn(Stream, @"\thispagestyle{empty}"); WriteLn(Stream, @"\ "); } /// protected override void ExportPageEnd(ReportPage page) { base.ExportPageEnd(page); WriteLn(Stream, @"\newpage"); } /// protected override void ExportBand(BandBase band) { base.ExportBand(band); if (band.Parent == null) return; // add export of band foreach (Base bandObject in band.ForEachAllConvectedObjects(this)) { if (bandObject is TableBase) { ExportTableObject(bandObject as TableBase); } else if (bandObject is TextObject) { ExportTextObject(bandObject as TextObject); } } } private StringBuilder PrepareString(string line) { StringBuilder sb = new StringBuilder(line.Length); foreach (char c in line) { switch (c) { case '%': sb.Append(@"\%"); break; case '$': sb.Append(@"\$"); break; case '&': sb.Append(@"\&"); break; case '_': sb.Append(@"\_"); break; case '{': sb.Append(@"\{"); break; case '}': sb.Append(@"\}"); break; case '#': sb.Append(@"\#"); break; case '^': sb.Append(@"\^"); break; case '~': sb.Append(@"\~"); break; case '\\': sb.Append(@"\textbackslash"); break; case '\n': sb.Append("\n\\\\"); break; default: sb.Append(c); break; } } return sb; } private void ExportTableObject(TableBase table) { if (table.ColumnCount > 0 && table.RowCount > 0) { float y = 0; for (int i = 0; i < table.RowCount; i++) { float x = 0; for (int j = 0; j < table.ColumnCount; j++) { if (!table.IsInsideSpan(table[j, i])) { TableCell textcell = table[j, i]; textcell.Left = x; textcell.Top = y; if (textcell is TextObject) ExportTextObject(textcell as TextObject); } x += (table.Columns[j]).Width; } y += (table.Rows[i]).Height; } } } private void ExportTextObject(TextObject textObject) { StringBuilder sb = new StringBuilder(); DrawTextFrame(sb, textObject.Text, textObject.Font, textObject.AbsLeft, textObject.AbsTop, textObject.Width, textObject.HorzAlign); Write(Stream, sb.ToString()); } private void DrawTextFrame(StringBuilder sb, string text, Font font, float left, float top, float width, HorzAlign horizAlign) { sb.Append(@"\").Append(GetBlockJustify(horizAlign)).Append("{"). Append(Math.Round(width * PT_PX, 2).ToString("R")).Append("pt}{"). Append(Math.Round(leftStartPos + left * PT_PX, 2).ToString("R")).Append("pt}{"). Append(Math.Round(topStartPos + top * PT_PX, 2).ToString("R")).Append("pt}{"). Append(font.Name).Append("}{").Append(font.Size.ToString()).Append("}{"). Append(GetFontStyle(font)). Append(PrepareString(text)). AppendLine("}"); } private string GetBlockJustify(HorzAlign horizAlign) { if (horizAlign == HorzAlign.Left) return "text"; else if (horizAlign == HorzAlign.Right) return "textright"; else if (horizAlign == HorzAlign.Center) return "textcenter"; else return "textjustify"; } private StringBuilder GetFontStyle(Font font) { StringBuilder sb = new StringBuilder(); if (font.Bold) sb.Append(@"\bfseries "); if (font.Italic) sb.Append(@"\itshape "); return sb; } #endregion /// /// Initializes a new instance of the class. /// public LaTeXExport() { } } }