using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Drawing; using FastReport.Export.TTF; using FastReport.Utils; namespace FastReport.Export.PS { /// /// Contains Dashes enum /// public enum Dashes { /// /// Specifies the Dash. /// Dash, /// /// Specifies the Dot. /// Dot, /// /// Specifies the DashDot. /// DashDot, /// /// Specifies the DashDotDot. /// DashDotDot, /// /// Specifies the Double line. /// Double } class PSDocument { protected float windowHeight; protected float windowWidth; protected StringBuilder psData = new StringBuilder(); protected bool textInCurves = false; internal bool TextInCurves { get { return textInCurves; } set { textInCurves = value; } } /// /// Create Window. /// public void CreateWindow() { if (Math.Round(windowWidth) == 595 && Math.Round(windowHeight) == 842) psData.Append("a4 "); } private bool RotatedTextIsVertical(float width, float height, float angle) { float diagonal = (float)Math.Sqrt(Math.Pow(width, 2) + Math.Pow(height, 2)); float sinA = height / diagonal; // angle left or right angle of diagonal float andleLRDiagonal = (float)(Math.Asin(sinA) / Math.PI * 180 * 2); // angle top or bottom angle of diagonal float andleTBDiagonal = (360 - andleLRDiagonal * 2) / 2; // angle should be in range from 0 to 360 angle %= 360; if (andleLRDiagonal / 2 < angle && angle < andleLRDiagonal / 2 + andleTBDiagonal || angle > andleLRDiagonal * 1.5 + andleTBDiagonal && angle < 360 - andleLRDiagonal / 2) return true; return false; } protected List TextAlignments(float x, ref float y, string HorizontalAlignment, string VerticalAlignment, float Width, float Height, Font font, List txt_lns, float PaddingLeft, float PaddingRight, float PaddingTop, float PaddingBottom, float BorderThikness) { Bitmap objBmpImage = new Bitmap(1, 1); Graphics objGraphics = Graphics.FromImage(objBmpImage); float Xold = x; float Yold = y; int N = txt_lns.Count; List x_alignments = new List(); using (Font f = new Font(font.FontFamily, font.Size * DrawUtils.ScreenDpiFX, font.Style)) { foreach (string line in txt_lns) { if (HorizontalAlignment == "Center") { x_alignments.Add(x + Width / 2 - objGraphics.MeasureString(line, f).Width / 2f * 0.75f); } else if (HorizontalAlignment == "Right") { x_alignments.Add(x + Width - objGraphics.MeasureString(line, f).Width * 0.75f); } else if (HorizontalAlignment == "Left") x_alignments.Add(x); else if (HorizontalAlignment == "Justify") x_alignments.Add(x); } } if (VerticalAlignment == "Center") { y = y - Height / 2f + ((float)font.Size) / 2; if (N > 1) y -= ((float)font.Size) / 2 * N; } if (VerticalAlignment == "Top") { y = y - Height + (float)font.Size; } if (VerticalAlignment == "Bottom") { if (N > 1) y = y - ((float)font.Size) * N; } //Paddings if (Yold - Height + (float)font.Size + PaddingTop > y) { y = Yold - Height + (float)font.Size + PaddingTop; } if (Yold - PaddingBottom < y) { y = Yold - PaddingBottom; } for (int i = 0; i < x_alignments.Count; i++) { if (Xold + PaddingLeft > x_alignments[i]) { x_alignments[i] = Xold + PaddingLeft; } if (Xold + Width - PaddingRight < x_alignments[i]) { x_alignments[i] = Xold + Width - PaddingRight; } } return x_alignments; } private bool gBorderLines(string BorderLines, out bool None, out bool Left, out bool Right, out bool Top, out bool Bottom) { string[] masLines = BorderLines.Split(',', ' ');//names lines borders bool All = false; None = false; Left = false; Right = false; Top = false; Bottom = false; for (int i = 0; i < masLines.Length; i++) { if (masLines[i] == "All") { All = true; } if (masLines[i] == "None") { None = true; } if (masLines[i] == "Left") { Left = true; } if (masLines[i] == "Right") { Right = true; } if (masLines[i] == "Top") { Top = true; } if (masLines[i] == "Bottom") { Bottom = true; } } return All; } private void createRotateText(float x, float y, string HorizontalAlignment, string VerticalAlignment, float Width, float Height, Font font, string textstr, float PaddingLeft, float PaddingRight, float PaddingTop, float PaddingBottom, float BorderThickness, string Foreground, string Background, float Angle) { List t_x = new List(); List t_y = new List(); bool textIsVertical = RotatedTextIsVertical(Width, Height, Angle); Bitmap objBmpImage = new Bitmap(1, 1); Graphics objGraphics = Graphics.FromImage(objBmpImage); double angle = ((360 - Angle % 360) * Math.PI / 180); float sin = (float)Math.Sin(angle); double cos = Math.Cos(angle); List txt_lns = new List(); string[] words = textstr.Split(' '); string line = ""; for (int n = 0; n < words.Length; n++) { string testLine = line; using (Font f = new Font(font.FontFamily, font.Size * DrawUtils.ScreenDpiFX, font.Style)) { if (!RotatedTextIsVertical(Width, Height, Angle) && (float)objGraphics.MeasureString(testLine + words[n], f).Width * 0.93f > Width || RotatedTextIsVertical(Width, Height, Angle) && (float)objGraphics.MeasureString(testLine + words[n], f).Width * 0.93f > Height) { if(line != "") txt_lns.Add(line); line = words[n] + " "; } else { testLine += words[n]; if (words[n].Contains("\n") || words[n].Contains("\r")) { int rn = testLine.IndexOf('\r') != -1 ? testLine.IndexOf('\r') : testLine.IndexOf('\n'); line = testLine.Remove(rn); txt_lns.Add(line); line = testLine.Remove(0, rn).Replace("\r", "").Replace("\n", "") + " "; } else line = testLine + " "; } } } if (txt_lns.Count == 0) txt_lns.Add(line); else if (txt_lns[txt_lns.Count - 1] != line) txt_lns.Add(line); // perform coordinates float Xold = x; float Yold = y; int N = txt_lns.Count; SizeF textSize; using (Font f = new Font(font.FontFamily, font.Size * DrawUtils.ScreenDpiFX, font.Style)) { foreach (string ln in txt_lns) { textSize = objGraphics.MeasureString(ln, f); y = Yold; if (!textIsVertical) { if (HorizontalAlignment == "Center") { int negativSin = 1; if (Angle > 180) negativSin = -1; t_x.Add(x + (Width - textSize.Width * (float)cos + textSize.Height * sin * negativSin) / 2); } else if (HorizontalAlignment == "Right" || VerticalAlignment == "Top" && textIsVertical) { t_x.Add(x + Width - objGraphics.MeasureString(ln, f).Width * 0.75f); } else if (HorizontalAlignment == "Left") t_x.Add(x); else if (HorizontalAlignment == "Justify") t_x.Add(x); } else { if (VerticalAlignment == "Center") { int negativSin = 1; if (Angle > 180) negativSin = -1; t_x.Add(x + (Width - textSize.Width * (float)cos + textSize.Height * sin * negativSin) / 2); } else if (VerticalAlignment == "Top" && textIsVertical) { t_x.Add(x + Width - objGraphics.MeasureString(ln, f).Height * 0.75f); } else if (VerticalAlignment == "Bottom" && textIsVertical) t_x.Add(x); } if (VerticalAlignment == "Center") { y = (y + ((float)font.Size / 2) + (Height - textSize.Height * 0.75f * (float)cos - textSize.Width * 0.75f * -sin) / 2); if (N > 1) y -= ((float)font.Size) / 2 * N; } if (VerticalAlignment == "Top") { y = y + (float)font.Size; if (textIsVertical && Angle % 360 >= 180) { y += Height; } } if (VerticalAlignment == "Bottom") { y = y - ((float)font.Size) / 2 * N; if (textIsVertical && Angle % 360 >= 180) { y += Height; } } t_y.Add(y); } } // create Glyphs ExportTTFFont pdffont = new ExportTTFFont(font); float cur_x; float cur_y; for (int i = 0; i < txt_lns.Count; i++) { ExportTTFFont.RunInfo[] runs = pdffont.GetFontRuns(txt_lns[i], false, font); foreach (var run in runs) { ExportTTFFont.GlyphTTF[] txt = pdffont.GetGlyphPath(run); cur_y = t_y[i]; if (RotatedTextIsVertical(Width, Height, Angle)) cur_y += i * ((float)cos * font.GetHeight() * DrawUtils.ScreenDpiFX * 0.75f); cur_x = t_x[i] + i * (sin * font.GetHeight() * DrawUtils.ScreenDpiFX * 0.75f) + run.OffsetX; foreach (ExportTTFFont.GlyphTTF g in txt) { if (g.Path.PointCount == 0) { cur_x += (float)cos * g.Width * 0.75f; cur_y += -sin * g.Width * 0.75f; continue; } System.Drawing.Drawing2D.Matrix matrix = new System.Drawing.Drawing2D.Matrix(); matrix.Rotate(Angle); g.Path.Transform(matrix); RectangleF rct = g.Path.GetBounds(matrix); PointF[] ps = g.Path.PathPoints; byte[] pt = g.Path.PathTypes; for (int j = 0; j < g.Path.PointCount;) { switch (pt[j]) { case 0://start if (j > 0) ClosePath(); MoveTo((cur_x + ps[j].X * 0.75f), cur_y + ps[j].Y * 0.75f); j++; break; case 1://line AppendLine(cur_x + ps[j].X * 0.75f, cur_y + ps[j].Y * 0.75f); j++; break; case 3://interpolate bezier AppendBezier(cur_x, cur_y, ps[j], ps[j + 1], ps[j + 2]); j += 3; break; default: i++; break; } } ClosePath(); EndFig(Foreground, Background); cur_x += (float)cos * g.Width * 0.75f; cur_y += -sin * g.Width * 0.75f; } } } psData.Append("\n"); } private void createText(float x, float y, string HorizontalAlignment, string VerticalAlignment, float Width, float Height, Font font, string textstr, float PaddingLeft, float PaddingRight, float PaddingTop, float PaddingBottom, float BorderThickness, string Foreground, string Background, float Angle) { List t_x; float t_y = y; Bitmap objBmpImage = new Bitmap(1, 1); Graphics objGraphics = Graphics.FromImage(objBmpImage); List txt_lns = new List(); string[] words = textstr.Split(' '); string line = ""; for (int n = 0; n < words.Length; n++) { string testLine = line + words[n]; using (Font f = new Font(font.FontFamily, font.Size * DrawUtils.ScreenDpiFX, font.Style)) { if ((float)objGraphics.MeasureString(testLine, f).Width * 0.75f > Width) { txt_lns.Add(line); line = words[n] + " "; } else { if (words[n].Contains("\n") || words[n].Contains("\r")) { int rn = testLine.IndexOf('\r') != -1 ? testLine.IndexOf('\r') : testLine.IndexOf('\n'); line = testLine.Remove(rn); txt_lns.Add(line); line = testLine.Remove(0, rn).Replace("\r", "").Replace("\n", "") + " "; } else line = testLine + " "; } } } if (txt_lns.Count == 0) txt_lns.Add(line); else if (txt_lns[txt_lns.Count - 1] != line) txt_lns.Add(line); t_x = TextAlignments(x, ref t_y, HorizontalAlignment, VerticalAlignment, Width, Height, font, txt_lns, PaddingLeft, PaddingRight, PaddingTop, PaddingBottom, BorderThickness); if (textInCurves) AddCurveTextLine(t_x, t_y, Foreground, Background, font, Width, Height, txt_lns, Angle); else AddTextLine(t_x, t_y, Foreground, font, Width, Height, txt_lns, Angle); } private void AddTextLine(List t_x, float t_y, string Foreground, Font font, float Width, float Height, List txt_lns, float Angle) { bool fstart = true; string internal_data = ""; string gsave; string coords; float cur_y = 0f; for (int i = 0; i < txt_lns.Count; i++) { string text_col = ColorToPsRgb(Foreground); if (Angle == 0) internal_data = "/" + PSFont(font.Name) + " findfont " + FloatToString(font.Size) + " scalefont setfont " + FloatToString(t_x[i]) + " " + FloatToString(windowHeight - t_y - Height) + " moveto " + text_col + " setrgbcolor (" + txt_lns[i] + ") show "; else { if (Angle <= 90) { t_x[i] += Width / 2; t_y -= Height / 2; } if (fstart) { gsave = " gsave "; fstart = false; coords = FloatToString(t_x[i]) + " " + FloatToString(windowHeight - t_y - Height) + " translate 0 0 moveto " + -Angle + " rotate "; } else { gsave = ""; coords = FloatToString(t_x[i] - t_x[0]) + " " + FloatToString(cur_y) + " moveto "; } cur_y -= font.GetHeight() * DrawUtils.ScreenDpiFX * 0.75f; internal_data = gsave + "/" + font.Name + " findfont " + FloatToString(font.Size) + " scalefont setfont " + coords + text_col + " setrgbcolor (" + txt_lns[i] + ") show "; if (i == txt_lns.Count - 1) internal_data += "grestore "; } psData.Append(internal_data + "\n"); t_y += font.GetHeight() * DrawUtils.ScreenDpiFX * 0.75f; } } /// Add TextLine in curves private void AddCurveTextLine(List t_x, float t_y, string Foreground, string Background, Font font, float Width, float Height, List txt_lns, float Angle) { ExportTTFFont pdffont = new ExportTTFFont(font); float cur_y = t_y + Height; for (int i = 0; i < txt_lns.Count; i++) { ExportTTFFont.RunInfo[] runs = pdffont.GetFontRuns(txt_lns[i], false, font); foreach (var run in runs) { ExportTTFFont.GlyphTTF[] txt = pdffont.GetGlyphPath(run); float cur_x = t_x[i] + run.OffsetX; if (Angle == 0) { foreach (ExportTTFFont.GlyphTTF g in txt) { if (g.Path.PointCount == 0) { cur_x += g.Width * 0.75f; continue; } PointF[] ps = g.Path.PathPoints; byte[] pt = g.Path.PathTypes; for (int j = 0; j < g.Path.PointCount;) { switch (pt[j]) { case 0://start if (j > 0) ClosePath(); MoveTo(cur_x + ps[j].X * 0.75f, cur_y + ps[j].Y * 0.75f); j++; break; case 1://line AppendLine(cur_x + ps[j].X * 0.75f, cur_y + ps[j].Y * 0.75f); j++; break; case 3://interpolate bezier AppendBezier(cur_x, cur_y, ps[j], ps[j + 1], ps[j + 2]); j += 3; break; default: i++; break; } } ClosePath(); EndFig(Foreground, Background); cur_x += g.Width * 0.75f; } cur_y += font.GetHeight() * DrawUtils.ScreenDpiFX * 0.75f; } } } psData.Append("\n"); } /// ///Method for add TextObject. /// public void AddTextObject(float x, float y, float Width, float Height, string HorizontalAlignment, string VerticalAlignment, string BorderBrush, float BorderThickness, float LeftLine, float TopLine, float RightLine, float BottomLine, string LeftLineDashStile, string TopLineDashStile, string RightLineDashStile, string BottomLineDashStile, string colorLeftLine, string colorTopLine, string colorRightLine, string colorBottomLine, bool Shadow, string ShadowColor, float ShadowWidth, string Background, string BorderLines, string Text, string Foreground, float PaddingLeft, float PaddingTop, float PaddingRight, float PaddingBottom, bool WordWrap, float Angle, bool Glass, string colorTop, Font font, bool isWatermark) { bool All = false; bool None = false; bool Left = false; bool Right = false; bool Top = false; bool Bottom = false; All = gBorderLines(BorderLines, out None, out Left, out Right, out Top, out Bottom); if (All && (LeftLine == TopLine && TopLine == RightLine && RightLine == BottomLine) && (LeftLineDashStile == TopLineDashStile && TopLineDashStile == RightLineDashStile && RightLineDashStile == BottomLineDashStile && BottomLineDashStile == "Solid") && (colorLeftLine == colorTopLine && colorTopLine == colorRightLine && colorRightLine == colorBottomLine /*&& colorBottomLine == Background*/)) { AddRectangle(x, y, Width, Height, BorderBrush, BorderThickness, Background, false); } else { if (Background != "none") { AddRectangle(x, y, Width, Height, BorderBrush, 0, Background, false); } if (Left || All) { if (LeftLineDashStile == "Solid") { AddLine(x, y, x, y + Height, colorLeftLine, LeftLine); } if (LeftLineDashStile == "Dash") { AddLine(x, y, x, y + Height, colorLeftLine, LeftLine, Dashes.Dash); } if (LeftLineDashStile == "Dot") { AddLine(x, y, x, y + Height, colorLeftLine, LeftLine, Dashes.Dot); } if (LeftLineDashStile == "DashDot") { AddLine(x, y, x, y + Height, colorLeftLine, LeftLine, Dashes.DashDot); } if (LeftLineDashStile == "DashDotDot") { AddLine(x, y, x, y + Height, colorLeftLine, LeftLine, Dashes.DashDotDot); } if (LeftLineDashStile == "Double") { AddLine(x, y, x, y + Height, colorLeftLine, LeftLine); AddLine(x - BorderThickness * 2, y - BorderThickness * 2, x - BorderThickness * 2, y + Height + BorderThickness * 2, colorLeftLine, LeftLine); } } if (Right || All) { if (RightLineDashStile == "Solid") { AddLine(x + Width, y, x + Width, y + Height, colorRightLine, RightLine); } if (RightLineDashStile == "Dash") { AddLine(x + Width, y, x + Width, y + Height, colorRightLine, RightLine, Dashes.Dash); } if (RightLineDashStile == "Dot") { AddLine(x + Width, y, x + Width, y + Height, colorRightLine, RightLine, Dashes.Dot); } if (RightLineDashStile == "DashDot") { AddLine(x + Width, y, x + Width, y + Height, colorRightLine, RightLine, Dashes.DashDot); } if (RightLineDashStile == "DashDotDot") { AddLine(x + Width, y, x + Width, y + Height, colorRightLine, RightLine, Dashes.DashDotDot); } if (RightLineDashStile == "Double") { AddLine(x + Width, y, x + Width, y + Height, colorRightLine, RightLine); AddLine(x + Width + BorderThickness * 2, y - BorderThickness * 2, x + Width + BorderThickness * 2, y + Height + BorderThickness * 2, colorRightLine, RightLine); } } if (Top || All) { if (TopLineDashStile == "Solid") { AddLine(x, y, x + Width, y, colorTopLine, TopLine); } if (TopLineDashStile == "Dash") { AddLine(x, y, x + Width, y, colorTopLine, TopLine, Dashes.Dash); } if (TopLineDashStile == "Dot") { AddLine(x, y, x + Width, y, colorTopLine, TopLine, Dashes.Dot); } if (TopLineDashStile == "DashDot") { AddLine(x, y, x + Width, y, colorTopLine, TopLine, Dashes.DashDot); } if (TopLineDashStile == "DashDotDot") { AddLine(x, y, x + Width, y, colorTopLine, TopLine, Dashes.DashDotDot); } if (TopLineDashStile == "Double") { AddLine(x, y, x + Width, y, colorTopLine, TopLine); AddLine(x - BorderThickness * 2, y - BorderThickness * 2, x + Width + BorderThickness * 2, y - BorderThickness * 2, colorTopLine, TopLine); } } if (Bottom || All) { if (BottomLineDashStile == "Solid") { AddLine(x, y + Height, x + Width, y + Height, colorBottomLine, BottomLine); } if (BottomLineDashStile == "Dash") { AddLine(x, y + Height, x + Width, y + Height, colorBottomLine, BottomLine, Dashes.Dash); } if (BottomLineDashStile == "Dot") { AddLine(x, y + Height, x + Width, y + Height, colorBottomLine, BottomLine, Dashes.Dot); } if (BottomLineDashStile == "DashDot") { AddLine(x, y + Height, x + Width, y + Height, colorBottomLine, BottomLine, Dashes.DashDot); } if (BottomLineDashStile == "DashDotDot") { AddLine(x, y + Height, x + Width, y + Height, colorBottomLine, BottomLine, Dashes.DashDotDot); } if (BottomLineDashStile == "Double") { AddLine(x, y + Height, x + Width, y + Height, colorBottomLine, BottomLine); AddLine(x - BorderThickness * 2, y + Height + BorderThickness * 2, x + Width + BorderThickness * 2, y + Height + BorderThickness * 2, colorBottomLine, BottomLine); } } } //Glass-------------------- if (Glass) { AddRectangle(x, y, Width, Height / 2, BorderBrush, 0, colorTop, false); AddRectangle(x, y + Height / 2, Width, Height / 2, BorderBrush, 0, Background, false); } //Shadow------------------- if (Shadow) { AddLine(x + ShadowWidth, y + Height + ShadowWidth / 2, x + Width + ShadowWidth, y + Height + ShadowWidth / 2, ShadowColor, ShadowWidth); AddLine(x + Width + ShadowWidth / 2, y + ShadowWidth, x + Width + ShadowWidth / 2, y + Height + ShadowWidth, ShadowColor, ShadowWidth); } if (Text != null) { if(isWatermark && textInCurves) createRotateText(x, y, HorizontalAlignment, VerticalAlignment, Width, Height, font, Text, PaddingLeft, PaddingRight, PaddingTop, PaddingBottom, BorderThickness, Foreground, Background, Angle); else createText(x, y, HorizontalAlignment, VerticalAlignment, Width, Height, font, Text, PaddingLeft, PaddingRight, PaddingTop, PaddingBottom, BorderThickness, Foreground, Background, Angle); } } /// /// Method to add rectangle. /// public void AddRectangle(float x, float y, float Width, float Height, string Stroke, float StrokeThickness, string Fill, bool Rounded) { if (StrokeThickness == 0 && Fill == "none") return; string rgb_stroke; string rgb_fill; string fill_str = ""; string border_col = ""; string rect_stroke = ""; string gsave = "gsave "; string grestore = "grestore "; if (StrokeThickness == 0) { gsave = ""; grestore = ""; } else { rgb_stroke = ColorToPsRgb(Stroke); border_col = rgb_stroke + " setrgbcolor "; } if (Fill != "none") { rgb_fill = ColorToPsRgb(Fill); fill_str = gsave + rgb_fill + " setrgbcolor fill " + grestore; } rect_stroke = FloatToString(StrokeThickness) + " setlinewidth "; string internal_data; if (Rounded) { string x1 = FloatToString(x); string y1 = FloatToString(windowHeight - y - Height); string x2 = FloatToString(x); string y2 = FloatToString(windowHeight - y); string x3 = FloatToString(x + Width); string y3 = FloatToString(windowHeight - y); ; string x4 = FloatToString(x + Width); string y4 = FloatToString(windowHeight - y - Height); internal_data = FloatToString(StrokeThickness) + " setlinewidth " + FloatToString(x + Width / 2) + " " + FloatToString(windowHeight - y - Height) + " moveto " + x1 + " " + y1 + " " + x2 + " " + y2 + " 5 arct " + x2 + " " + y2 + " " + x3 + " " + y3 + " 5 arct " + x3 + " " + y3 + " " + x4 + " " + y4 + " 5 arct " + x4 + " " + y4 + " " + x1 + " " + y1 + " 5 arct closepath " + fill_str + border_col + "stroke"; } else { internal_data = FloatToString(StrokeThickness) + " setlinewidth " + FloatToString(x) + " " + FloatToString(windowHeight - y - Height) + " newpath moveto " + FloatToString(x) + " " + FloatToString(windowHeight - y) + " lineto " + FloatToString(x + Width) + " " + FloatToString(windowHeight - y) + " lineto " + FloatToString(x + Width) + " " + FloatToString(windowHeight - y - Height) + " lineto closepath " + fill_str + border_col + "stroke"; } psData.Append(internal_data + "\n"); } /// /// Method for add ellips. /// public void AddEllipse(float x, float y, float Width, float Height, string Stroke, float StrokeThickness, string Fill) { if (StrokeThickness == 0 && Fill == "none") return; string rgb_stroke; string rgb_fill; string fill_str = ""; string border_col = ""; string ell_stroke = ""; string gsave = "gsave "; string grestore = "grestore "; if (StrokeThickness == 0) { gsave = ""; grestore = ""; } else { rgb_stroke = ColorToPsRgb(Stroke); border_col = rgb_stroke + " setrgbcolor "; } if (Fill != "none") { rgb_fill = ColorToPsRgb(Fill); fill_str = gsave + rgb_fill + " setrgbcolor fill " + grestore; } ell_stroke = FloatToString(StrokeThickness) + " setlinewidth "; string internal_data = ""; internal_data = FloatToString(StrokeThickness) + " setlinewidth " + FloatToString(x + Width / 2) + " " + FloatToString(windowHeight - y - Height / 2) + " " + FloatToString(Width / 2) + " 0 360 arc closepath " + fill_str + border_col + "stroke"; psData.Append(internal_data + "\n"); } /// /// Method for add triangle. /// public void AddTriangle(float x, float y, float Width, float Height, string Stroke, float StrokeThickness, string Fill) { if (StrokeThickness == 0 && Fill == "none") return; float x2 = Width + x; float y2 = y; float x3 = x + Width / 2; float y3 = y; string rgb_stroke; string rgb_fill; string fill_str = ""; string border_col = ""; string tri_stroke = ""; string gsave = "gsave "; string grestore = "grestore "; if (StrokeThickness == 0) { gsave = ""; grestore = ""; } else { rgb_stroke = ColorToPsRgb(Stroke); border_col = rgb_stroke + " setrgbcolor "; } if (Fill != "none") { rgb_fill = ColorToPsRgb(Fill); fill_str = gsave + rgb_fill + " setrgbcolor fill " + grestore; } tri_stroke = FloatToString(StrokeThickness) + " setlinewidth "; string internal_data = FloatToString(StrokeThickness) + " setlinewidth " + FloatToString(x) + " " + FloatToString(windowHeight - y - Height) + " newpath moveto " + FloatToString(x2) + " " + FloatToString(windowHeight - Height - y2) + " lineto " + FloatToString(x3) + " " + FloatToString(windowHeight - y3) + " lineto closepath " + fill_str + border_col + "stroke"; psData.Append(internal_data + "\n"); } /// /// Method for add Diamond. /// public void AddDiamond(float x, float y, float Width, float Height, string Stroke, float StrokeThickness, string Fill) { float x1 = Width / 2 + x; float y1 = y; float x2 = Width + x; float y2 = Height / 2 + y; float x3 = Width / 2 + x; float y3 = y; float x4 = x; float y4 = Height / 2 + y; string rgb_stroke; string rgb_fill; string fill_str = ""; string border_col = ""; string tri_stroke = ""; string gsave = "gsave "; string grestore = "grestore "; if (StrokeThickness == 0) { gsave = ""; grestore = ""; } else { rgb_stroke = ColorToPsRgb(Stroke); border_col = rgb_stroke + " setrgbcolor "; } if (Fill != "none") { rgb_fill = ColorToPsRgb(Fill); fill_str = gsave + rgb_fill + " setrgbcolor fill " + grestore; } tri_stroke = FloatToString(StrokeThickness) + " setlinewidth "; string internal_data = FloatToString(StrokeThickness) + " setlinewidth " + FloatToString(x1) + " " + FloatToString(windowHeight - y1 - Height) + " newpath moveto " + FloatToString(x2) + " " + FloatToString(windowHeight - y2) + " lineto " + FloatToString(x3) + " " + FloatToString(windowHeight - y3) + " lineto " + FloatToString(x4) + " " + FloatToString(windowHeight - y4) + " lineto closepath " + fill_str + border_col + "stroke"; psData.Append(internal_data + "\n"); } /// ///Method for add line. /// public void AddLine(float x, float y, float x2, float y2, string Stroke, float StrokeThickness) { StartFig(StrokeThickness); MoveTo(x, y); AppendLine(x2, y2); EndFig(Stroke); } /// ///Method for add line with dash. /// public void AddLine(float x, float y, float x2, float y2, string Stroke, float StrokeThickness, Dashes dash) { string line_col = ""; string line_stroke = ""; string rgb = ColorToPsRgb(Stroke); string StrokeDashArray = ""; if (dash == Dashes.Dash) { StrokeDashArray = " [5] 0 setdash "; } if (dash == Dashes.Dot) { StrokeDashArray = "[2 2] 0 setdash"; } if (dash == Dashes.DashDot) { StrokeDashArray = "[2 2 5 2] 0 setdash"; } if (dash == Dashes.DashDotDot) { StrokeDashArray = "[2 2 2 2 5 2] 0 setdash"; } if (dash == Dashes.Double) { StrokeDashArray = ""; AddLine(x + 10, y + 10, x2 + 10, y2 + 10, Stroke, StrokeThickness); } line_col = rgb + " setrgbcolor "; line_stroke = FloatToString(StrokeThickness) + " setlinewidth " + StrokeDashArray + " "; string internal_data = line_stroke + FloatToString(x) + " " + FloatToString(windowHeight - y) + " newpath moveto " + FloatToString(x2) + " " + FloatToString(windowHeight - y2) + " lineto " + line_col + "stroke [ ] 0 setdash"; psData.Append(internal_data + "\n"); } public void AddBezier(float x, float y, PointF p0, PointF p1, PointF p2, PointF p3, string Stroke, float StrokeThickness) { string line_col = ""; string line_stroke = ""; string rgb = ColorToPsRgb(Stroke); line_col = rgb + " setrgbcolor "; line_stroke = FloatToString(StrokeThickness) + " setlinewidth "; string internal_data = line_stroke + FloatToString(x + p0.X) + " " + FloatToString(windowHeight - y - p0.Y) + " newpath moveto " + FloatToString(x + p1.X) + " " + FloatToString(windowHeight - y - p1.Y) + " " + FloatToString(x + p2.X) + " " + FloatToString(windowHeight - y - p2.Y) + " " + FloatToString(x + p3.X) + " " + FloatToString(windowHeight - y - p3.Y) + " " + " curveto " + line_col + "stroke"; psData.Append(internal_data + "\n"); } private void AppendBezier(float x, float y, PointF p1, PointF p2, PointF p3) { string internal_data = FloatToString(x + p1.X * 0.75f) + " " + FloatToString(windowHeight - y - p1.Y * 0.75f) + " " + FloatToString(x + p2.X * 0.75f) + " " + FloatToString(windowHeight - y - p2.Y * 0.75f) + " " + FloatToString(x + p3.X * 0.75f) + " " + FloatToString(windowHeight - y - p3.Y * 0.75f) + " " + " curveto "; psData.Append(internal_data + "\n"); } private void AppendLine(float x2, float y2) { string internal_data = FloatToString(x2) + " " + FloatToString(windowHeight - y2) + " lineto "; psData.Append(internal_data); } private void StartFig(float StrokeThickness) { string line_stroke = " "; line_stroke = FloatToString(StrokeThickness) + " setlinewidth "; psData.Append(line_stroke + "\n"); } private void MoveTo(float x, float y) { psData.Append(" " + FloatToString(x) + " " + FloatToString(windowHeight - y) + " moveto "); } private void ClosePath() { psData.Append(" closepath "); } private void EndFig(string stroke, string fill) { string rgb_stroke = ColorToPsRgb(stroke); string l = ""; string rgb_fill = ColorToPsRgb(stroke); l += /*" gsave " +*/ rgb_fill + " setrgbcolor fill "/*grestore "*/; psData.Append(l + rgb_stroke + "\n"); } private void EndFig(string stroke) { string rgb_stroke = ColorToPsRgb(stroke); psData.Append(" gsave " + rgb_stroke + " setrgbcolor stroke grestore "); } public void DeclareImage(string name, string hex) { psData.Append("/" + name + " (" + hex + ") def \n"); } /// /// Add image /// /// /// /// /// /// /// public void AddImage(string filename, string format, float left, float top, float width, float height) { if (!String.IsNullOrEmpty(filename)) { string s_picwidth = FloatToString((int)width); string s_picheight = FloatToString((int)height); width *= 0.75f; height *= 0.75f; string s_left = FloatToString(left); string s_top = FloatToString(windowHeight - height - top); string img = " gsave " + s_left + " " + s_top + " translate " + //set lower left of image at (360, 72) FloatToString(Math.Round(width)) + " " + FloatToString(Math.Round(height)) + " scale " + //size of rendered image is 175 points by 47 points s_picwidth + " " + //number of columns per row s_picheight + " " + //number of rows "8 " + //bits per color channel (1, 2, 4, or 8) "[" + s_picwidth + " 0 0 -" + s_picheight + " 0 " + s_picheight + "] " + //transform array... maps unit square to pixel "(" + filename + "." + format + ") (r) file /DCTDecode filter " + //opens the file and filters the image data "false " + //pull channels from separate sources "3 " + // 3 color channels (RGB) "colorimage " + "grestore "; psData.Append(img + "\n"); } } /// /// Add image as hex code /// /// /// /// /// /// public void AddImage(string varname, float left, float top, float width, float height) { string s_picwidth = FloatToString((int)width); string s_picheight = FloatToString((int)height); width *= 0.75f; height *= 0.75f; string s_left = FloatToString(left); string s_top = FloatToString(windowHeight - height - top); string img = " gsave " + s_left + " " + s_top + " translate " + //set lower left of image at (360, 72) FloatToString(Math.Round(width)) + " " + FloatToString(Math.Round(height)) + " scale " + //size of rendered image is 175 points by 47 points s_picwidth + " " + //number of columns per row s_picheight + " " + //number of rows "8 " + //bits per color channel (1, 2, 4, or 8) "[" + s_picwidth + " 0 0 -" + s_picheight + " 0 " + s_picheight + "] " + //transform array... maps unit square to pixel varname + " /ASCIIHexDecode filter 0 dict" + " /DCTDecode filter " + "false " + //pull channels from separate sources "3 " + // 3 color channels (RGB) "colorimage " + "grestore "; psData.Append(img + "\n"); } /// /// End of each page /// public void Finish() { psData.Append("showpage\n"); } /// /// Save file. /// public void Save(string filename) { System.IO.File.WriteAllText(filename, psData.ToString()); } /// /// Save stream. /// public void Save(Stream stream) { stream.Write(System.Text.Encoding.UTF8.GetBytes(psData.ToString()), 0, System.Text.Encoding.UTF8.GetBytes(psData.ToString()).Length); } string ColorToPsRgb(string htmlcolor) { return FloatToString((double)System.Drawing.ColorTranslator.FromHtml(htmlcolor).R / 255) + " " + FloatToString((double)System.Drawing.ColorTranslator.FromHtml(htmlcolor).G / 255) + " " + FloatToString((double)System.Drawing.ColorTranslator.FromHtml(htmlcolor).B / 255); } private string FloatToString(double flt) { return ExportUtils.FloatToString(flt); } private string PSFont(string font) { return font.Replace(" ", "-"); } /// /// public PSDocument(float Width, float Height) { windowHeight = Height; windowWidth = Width; CreateWindow(); } public PSDocument() { windowHeight = 842; windowWidth = 595; } } }