using System; using System.Collections.Generic; using System.Text; using iTextSharp.text; using iTextSharp.text.pdf; using iTextSharp.text.factories; using Itenso.Rtf; using Itenso.Rtf.Parser; using Itenso.Rtf.Interpreter; using Itenso.Rtf.Support; using System.IO; namespace Volian.Print.Library { [Flags] public enum TableScrunching:short // RHM20150507 Table Scrunch { None=0, Phase1=1, Phase2=2, Phase3=4, Phase4=8, Phase5=16, Phase6=32, Phase7=64, Phase8=128, Phase9=256, Phase10=512, AllPhases=1+2+4+8+16+32+64+128+256+512 } public class Rtf2Pdf { private string _Rtf; public string Rtf { get { return _Rtf; } set { _Rtf = value; } } private string _FileName; public string FileName { get { return _FileName; } set { _FileName = value; } } public Rtf2Pdf(string rtf, string fileName) { _Rtf = rtf; _FileName = fileName; } public void Process() { Document document = new Document(PageSize.LETTER); PdfWriter writer = PdfWriter.GetInstance(document, new FileStream(FileName, FileMode.Create)); document.Open(); // Open RTF Document IRtfDocument rtfDoc = RtfInterpreterTool.BuildDoc(Rtf); Rtf2iTextSharp rtf2IText = new Rtf2iTextSharp(rtfDoc); Paragraph para = rtf2IText.Convert(); para.SetLeading(12F, 0); PdfContentByte cb = writer.DirectContent; SampleParagraphs(para, cb, 792-36, 252, 36); para.Add(new Chunk(" (continued)",para.Font)); SampleParagraphs(para, cb, 792 - 36, 252, 324); // Close the document document.Close(); } private static void SampleParagraphs(Paragraph para, PdfContentByte cb, float yTop, float width, float x) { while (yTop > 0) { float newYTop = TextAt(cb, para, x, yTop - 12F, width, 100,"",36); width -= 16; yTop = newYTop; } } private static bool _PdfDebug = true; public static bool PdfDebug { get { return Rtf2Pdf._PdfDebug; } set { Rtf2Pdf._PdfDebug = value; } } private static System.Drawing.PointF _Offset = new System.Drawing.PointF(0, 0); public static System.Drawing.PointF Offset { get { return Rtf2Pdf._Offset; } set { Rtf2Pdf._Offset = value; } } public static float FillWidth = 0; // max text width (used in autoToc code) private static int _TextAtCounter = 0; public static int TextAtCounter { get { return Rtf2Pdf._TextAtCounter; } set { Rtf2Pdf._TextAtCounter = value; } } private static int NextTextAtCounter { get { int retval = ++TextAtCounter; //if (InList(retval, 461)) Console.WriteLine("TextAt {0}", retval); return retval; } } public class VlnSplitCharacter : ISplitCharacter { public bool IsSplitCharacter(int start, int current, int end, char[] cc, PdfChunk[] ck) { return (cc[current] == ' '); } public bool IsSplitCharacter(char c) { return (c == ' '); } } private static TableScrunching _AllowTableScrunching = TableScrunching.AllPhases; // RHM20150507 Table Scrunch public static TableScrunching AllowTableScrunching { get { return Rtf2Pdf._AllowTableScrunching; } set { Rtf2Pdf._AllowTableScrunching = value; } } public static bool GetTableScrunchingStatus(TableScrunching val) { return (val & _AllowTableScrunching) == val; } public static VlnSplitCharacter mySplitter = new VlnSplitCharacter(); public static float TextAt(PdfContentByte cb, Paragraph iParagraph, float x, float y, float width, float height, string debugText, float yBottomMargin) { // Change the chunks to only split on spaces rather than spaces and hyphens foreach (Chunk chk in iParagraph) { if (chk.Attributes == null || !chk.Attributes.ContainsKey("NoSplit")) { if (chk.Attributes == null) chk.Attributes = new System.Collections.Hashtable(); chk.SetSplitCharacter(mySplitter); chk.Attributes.Add("NoSplit", false); } } VlnSvgPageHelper _MyPageHelper = cb.PdfWriter.PageEvent as VlnSvgPageHelper; PdfLayer textLayer = _MyPageHelper == null ? null : _MyPageHelper.TextLayer; float left = x + Offset.X; float top = y + Offset.Y + _MyPageHelper.TableAdjustment;// RHM20150525 - Table Scrunch float right = left + width; float bottom = top - height; ColumnText myColumnText = new ColumnText(cb); myColumnText.SetSimpleColumn(left, top, left + width, yBottomMargin); myColumnText.AddElement(iParagraph); float pos = myColumnText.YLine; // Save the position to be used if the paragraph fits int status = myColumnText.Go(true); // Check to see if it will fit on the page. if (ColumnText.HasMoreText(status)) return 0;// Paragraph won't fit. Return 0; myColumnText.YLine = pos; // restore the location on the page myColumnText.AddElement(iParagraph); // add in paragraph if (textLayer != null) cb.BeginLayer(textLayer); myColumnText.Go(false); // Draw the paragraph FillWidth = myColumnText.FilledWidth; if (textLayer != null) cb.EndLayer(); // Approximate Descent by using Leading divided by 5. float yDescent = iParagraph.Leading / 5; // If the BaseFont is available, calculate yAdj on the basis of the Descent if (iParagraph.Font.BaseFont != null) yDescent = -iParagraph.Font.BaseFont.GetDescentPoint("Almg", iParagraph.Font.Size); if (PdfDebug) { // be very careful around the following line, if the cursor 'touches' // NextTextAtCounter, it is incremented and the 'next' value may not be what // was seen as the UniqueNumber in the pdf. int next = NextTextAtCounter; // buffer (unnecessary comments) so // that cursor does NOT touch 'NextTextAtCounter' // as easily //if (InList(next,2958, 2961)) Console.WriteLine("Stop at UniqueNumber"); string dbt = string.Format("[{0}]{1}", next, debugText ?? ""); DrawPdfDebug(cb, left, top, left + width, myColumnText.YLine, dbt, yDescent); } return myColumnText.YLine; } private static bool InList(int value, params int [] examples) { foreach (int ex in examples) if (ex == value) return true; return false; } public static float FigureAt(PdfContentByte cb, iTextSharp.text.Image image, float x, float y, float width, float height, string debugText, float yBottommargin, bool hasBorder) { VlnSvgPageHelper _MyPageHelper = cb.PdfWriter.PageEvent as VlnSvgPageHelper; PdfLayer textLayer = _MyPageHelper == null ? null : _MyPageHelper.TextLayer; float left = x + Offset.X; float top = y + Offset.Y; float bottom = top - height; image.ScaleAbsoluteWidth(width); image.ScaleAbsoluteHeight(height); image.SetAbsolutePosition(left, bottom); if (textLayer != null) cb.BeginLayer(textLayer); cb.AddImage(image); if (hasBorder) { iTextSharp.text.Color boxColor = new iTextSharp.text.Color(System.Drawing.Color.Black); // (PrintOverride.OverrideBoxColor(System.Drawing.Color.Black)); cb.SetColorStroke(boxColor); cb.SetLineWidth(.85F); cb.Rectangle(left-1.5F, bottom-1.5F, width+3, height+3); cb.Stroke(); } if (textLayer != null) cb.EndLayer(); return bottom; } private static float _GridTopAdjust = -10; public static float GridTopAdjust { get { return _GridTopAdjust; } set { _GridTopAdjust = value; } } public static float GridAt(PdfContentByte cb, vlnTable myGrid, float x, float y, float width, float height, string debugText, float yBottomMargin, bool hasBorder) { //VlnSvgPageHelper _MyPageHelper = cb.PdfWriter.PageEvent as VlnSvgPageHelper; // RHM20150507 Table Scrunch //PdfLayer textLayer = _MyPageHelper == null ? null : _MyPageHelper.TextLayer; // RHM20150507 Table Scrunch float left = x + Offset.X; float top = y + Offset.Y; float right = left + width; float bottom = top - height; ColumnText myColumnText = new ColumnText(cb); myColumnText.SetSimpleColumn(left, top, left + width, yBottomMargin); //if (textLayer != null) cb.BeginLayer(textLayer); // RHM20150507 Table Scrunch myGrid.ToPdf(myColumnText, left, top + GridTopAdjust); //if (textLayer != null) cb.EndLayer(); // RHM20150507 Table Scrunch return bottom; } internal static void DrawPdfDebug(PdfContentByte cb, float left, float top, float right, float bottom, string debugText, float yDescent) { VlnSvgPageHelper _MyPageHelper = cb.PdfWriter.PageEvent as VlnSvgPageHelper; PdfLayer debugLayer = _MyPageHelper == null ? null : _MyPageHelper.DebugLayer; if (debugLayer == null) return; System.Drawing.Color sysColor = PrintOverride.OverrideDebugColor(System.Drawing.Color.Gray); cb.SaveState(); cb.BeginLayer(debugLayer); cb.SetColorStroke(new Color(sysColor)); cb.SetLineWidth(.1F); cb.MoveTo(left, top - yDescent); cb.LineTo(right, top - yDescent); cb.LineTo(right, bottom - yDescent); cb.LineTo(left, bottom - yDescent); cb.LineTo(left, top - yDescent); cb.Stroke(); if (debugText != "") { ColumnText ct = new ColumnText(cb); ct.SetSimpleColumn(left, 4 + top - yDescent, right, top - yDescent - 50); iTextSharp.text.Font font = FontFactory.GetFont("Arial", BaseFont.IDENTITY_H, BaseFont.EMBEDDED, 2); Chunk chk = new Chunk(debugText + string.Format(", Top = {0}",top), font); Phrase ph = new Phrase(chk); ct.AddElement(ph); cb.SetColorFill(new Color(sysColor)); ct.Go(); } cb.EndLayer(); cb.RestoreState(); } } }