123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567 |
- using FastReport.Barcode;
- using FastReport.Table;
- using FastReport.Utils;
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using System.Drawing.Drawing2D;
- using System.IO;
- using System.Linq;
- using System.Text;
- namespace FastReport.Export.Hpgl
- {
- /// <summary>
- /// Variants of filling
- /// </summary>
- public enum HpglFillMode
- {
- /// <summary>
- /// Solid filling of hatch and solid objects
- /// </summary>
- Solid,
- /// <summary>
- /// Draw only borders of hatch and solid objects
- /// </summary>
- Border
- }
- public partial class HpglExport : ExportBase
- {
- #region Fields
- private string path;
- private string fileNameWOext;
- private string extension;
- private string pageFileName;
- private int currentPage;
- private HpglDocument hpglDocument;
- private float pageHeight;
- private float pageWidth;
- private IGraphics hpglMeasureGraphics;
- private HpglFillMode fillMode;
- private float barcodesGap;
- #endregion // Fields
- /// <summary>
- /// Gets or sets lines/polygons gap for barcodes object
- /// </summary>
- public float BarcodesGap
- {
- get { return barcodesGap; }
- set { barcodesGap = value; }
- }
- /// <summary>
- /// Gets or sets the hpgl objects fill mode
- /// </summary>
- public HpglFillMode FillMode
- {
- get { return fillMode; }
- set { fillMode = value; }
- }
- /// <summary>
- /// Initializes a new instance of the <see cref="HpglExport"/> class.
- /// </summary>
- public HpglExport()
- {
- hpglDocument = new HpglDocument();
- HasMultipleFiles = true;
- hpglMeasureGraphics = new GdiGraphics(new Bitmap(1, 1));
- }
- #region Private Methods
- /// <summary>
- /// Save hpgl file.
- /// </summary>
- private void Save(string filename)
- {
- string hpglString = hpglDocument.ToString();
- File.WriteAllText(filename, hpglString);
- }
- /// <summary>
- /// Save hpgl stream.
- /// </summary>
- private void Save(Stream stream)
- {
- string hpglString = hpglDocument.ToString();
- byte[] encodedDfx = Encoding.UTF8.GetBytes(hpglString);
- stream.Write(encodedDfx, 0, encodedDfx.Length);
- }
- /// <summary>
- /// Add BandObject.
- /// </summary>
- private void AddBandObject(BandBase band)
- {
- using (TextObject newObj = new TextObject())
- {
- newObj.Left = band.AbsLeft;
- newObj.Top = band.AbsTop;
- newObj.Width = band.Width;
- newObj.Height = band.Height;
- newObj.Fill = band.Fill;
- newObj.Border = band.Border;
- AddTextObject(newObj, true);
- }
- }
- private void AddTable(TableBase table)
- {
- 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;
- Border oldBorder = textcell.Border.Clone();
- textcell.Border.Lines = BorderLines.None;
- if (textcell is TextObject)
- AddTextObject(textcell as TextObject, /*false*/ true);
- //else
- // AddPictureObject(textcell as ReportComponentBase);
- textcell.Border = oldBorder;
- AddBorder(textcell.Border, textcell.AbsLeft, textcell.AbsTop, textcell.Width, textcell.Height);
- }
- x += (table.Columns[j]).Width;
- }
- y += (table.Rows[i]).Height;
- }
- }
- /// <summary>
- /// Add TextObject.
- /// </summary>
- private void AddTextObject(TextObject obj, bool drawBorder)
- {
- float AbsLeft = obj.AbsLeft;
- float AbsTop = pageHeight * Units.Millimeters - obj.AbsTop;
- float Width = obj.Width;
- float Height = obj.Height;
- bool transformNeeded = obj.Angle != 0 || obj.FontWidthRatio != 1;
- if (transformNeeded)
- return;
- // draw background
- //if (obj.FillColor != Color.Transparent)
- // AddRectangleFill(AbsLeft, AbsTop, Width, Height, obj.FillColor);
- // WIP: draw text here
- //if (!string.IsNullOrWhiteSpace(obj.Text))
- //{
- // GraphicsPath myPath = new GraphicsPath();
- // // Set up all the string parameters.
- // string stringText = obj.Text;
- // FontFamily family = obj.Font.FontFamily;
- // int fontStyle = (int)obj.Font.Style;
- // float emSize = obj.Font.Size;
- // PointF origin = new PointF(0, 0);
- // StringFormat format = StringFormat.GenericDefault;
- // // Add the string to the path.
- // myPath.AddString(stringText,
- // family,
- // fontStyle,
- // emSize,
- // origin,
- // format);
- // AddGraphicsPath(myPath, obj.TextColor, 1, LineStyle.Solid, AbsLeft + Width / 2, AbsTop - Height / 2, true, true);
- // }
- // if (obj.Clip)
- if (obj.Underlines)
- AddUnderlines(obj);
- if (!String.IsNullOrEmpty(obj.Text))
- {
- using (Font f = new Font(obj.Font.FontFamily, obj.Font.Size, obj.Font.Style))
- {
- RectangleF textRect = new RectangleF(
- obj.AbsLeft + obj.Padding.Left,
- obj.AbsTop + obj.Padding.Top,
- obj.Width - obj.Padding.Horizontal,
- obj.Height - obj.Padding.Vertical);
- // break the text to paragraphs, lines, words and runs
- StringFormat format = obj.GetStringFormat(Report.GraphicCache /*cache*/, 0);
- Brush textBrush = Report.GraphicCache.GetBrush(obj.TextColor);
- AdvancedTextRenderer renderer = new AdvancedTextRenderer(obj.Text, hpglMeasureGraphics, f, textBrush, null,
- textRect, format, obj.HorzAlign, obj.VertAlign, obj.LineHeight, obj.Angle, obj.FontWidthRatio,
- obj.ForceJustify, obj.Wysiwyg, obj.HasHtmlTags, false, Zoom, Zoom, obj.InlineImageCache);
- float w = f.Height * 0.1f; // to match .net char X offset
- // invert offset in case of rtl
- if (obj.RightToLeft)
- w = -w;
- // we don't need this offset if text is centered
- if (obj.HorzAlign == HorzAlign.Center)
- w = 0;
- //XmlElement textContainer = DrawTextContainer(obj.AbsLeft, obj.AbsTop, f, obj.TextColor);
- // transform, rotate and scale coordinates if needed
- if (transformNeeded)
- {
- textRect.X = -textRect.Width / 2;
- textRect.Y = -textRect.Height / 2;
- float angle = (float)(obj.Angle * Math.PI / 180);
- float x = (obj.AbsLeft + obj.Width / 2);
- float y = (obj.AbsTop + obj.Height / 2);
- //AppndAngle(textContainer, angle, x, y);
- }
- // render
- foreach (AdvancedTextRenderer.Paragraph paragraph in renderer.Paragraphs)
- foreach (AdvancedTextRenderer.Line line in paragraph.Lines)
- {
- float lineOffset = 0;
- float lineHeight = line.CalcHeight();
- if (lineHeight > obj.Height)
- {
- if (obj.VertAlign == VertAlign.Center)
- lineOffset = -lineHeight / 2;//-
- else if (obj.VertAlign == VertAlign.Bottom)
- lineOffset = -lineHeight;//-
- }
- /* foreach (RectangleF rect in line.Underlines)
- {
- // DrawPDFUnderline(ObjectFontNumber, f, rect.Left, rect.Top, rect.Width, w,
- // obj.TextColor, transformNeeded, sb);
- }*/
- /*foreach (RectangleF rect in line.Strikeouts)
- {
- DrawStrikeout(f, rect.Left, rect.Top, rect.Width, w, obj.TextColor, transformNeeded);
- }*/
- foreach (AdvancedTextRenderer.Word word in line.Words)
- {
- //if (renderer.HtmlTags)
- // foreach (AdvancedTextRenderer.Run run in word.Runs)
- // using (Font fnt = run.GetFont())
- // {
- // AppndTspan(textContainer, run.Left, run.Top + lineOffset + lineHeight * 72 / 96/*magic*/,
- // w, run.Text, f);
- // }
- //else
- //AppndTspan(textContainer, word.Left, word.Top + lineOffset + lineHeight * 72 / 96/*magic*/,
- // w, word.Text, f);
- // --
- if (!string.IsNullOrWhiteSpace(word.Text))
- {
- GraphicsPath myPath = new GraphicsPath();
- // Set up all the string parameters.
- string stringText = word.Text;
- FontFamily family = obj.Font.FontFamily;
- int fontStyle = (int)obj.Font.Style;
- float emSize = obj.Font.Size;
- PointF origin = new PointF(0, 0 /*+ lineOffset + lineHeight*//*magic*/);
- // StringFormat format = StringFormat.GenericDefault;
- // Add the string to the path.
- myPath.AddString(stringText,
- family,
- fontStyle,
- emSize,
- origin,
- StringFormat.GenericDefault);
- float x = word.Left + w + (transformNeeded ? obj.AbsLeft : 0);
- float y = pageHeight * Units.Millimeters - word.Top - lineOffset - (transformNeeded ? obj.AbsTop : 0);
- float centerX = (obj.Width / 2) / Units.Millimeters;
- float centerY = (obj.Height / 2) / Units.Millimeters;
- PointF center = new PointF(centerX, centerY);
- float angle = (float)(obj.Angle * Math.PI / 180);
- AddGraphicsPath(myPath, obj.TextColor, 1 / 100.0f, LineStyle.Solid, x,
- y, true, true, angle, center);
- }
- // --
- }
- }
- }
- }
- if (drawBorder)
- AddBorder(obj.Border, obj.AbsLeft, obj.AbsTop, obj.Width, obj.Height);
- }
- #endregion // Private Methods
- #region Protected Methods
- /// <inheritdoc/>
- protected override void Start()
- {
- currentPage = 0;
- GeneratedStreams = new List<Stream>();
- if (FileName != "" && FileName != null)
- {
- path = Path.GetDirectoryName(FileName);
- fileNameWOext = Path.GetFileNameWithoutExtension(FileName);
- extension = Path.GetExtension(FileName);
- }
- else
- fileNameWOext = "hpglReport";
- }
- /// <summary>
- /// Begin exporting of page
- /// </summary>
- /// <param name="page"></param>
- protected override void ExportPageBegin(ReportPage page)
- {
- base.ExportPageBegin(page);
- pageHeight = ExportUtils.GetPageHeight(page);
- pageWidth = ExportUtils.GetPageWidth(page);
- hpglDocument = new HpglDocument();
- hpglDocument.Start(new SizeF(4000, 4000));
- // page borders
- if (page.Border.Lines != BorderLines.None)
- {
- using (TextObject pageBorder = new TextObject())
- {
- pageBorder.Border = page.Border;
- pageBorder.Left = 0;
- pageBorder.Top = 0;
- pageBorder.Width = (pageWidth - page.LeftMargin - page.RightMargin);
- pageBorder.Height = (pageHeight - page.TopMargin - page.BottomMargin);
- // AddTextObject(pageBorder, true);
- }
- }
- if (path != null && path != "")
- pageFileName = Path.Combine(path, fileNameWOext + currentPage.ToString() + extension);
- else
- pageFileName = null;
- }
- /// <summary>
- /// Export of Band
- /// </summary>
- /// <param name="band"></param>
- protected override void ExportBand(BandBase band)
- {
- base.ExportBand(band);
- ExportObj(band);
- foreach (Base c in band.ForEachAllConvectedObjects(this))
- {
- ExportObj(c);
- }
- }
- /// <summary>
- /// End exporting
- /// </summary>
- /// <param name="page"></param>
- protected override void ExportPageEnd(ReportPage page)
- {
- base.ExportPageEnd(page);
- //hpglDocument.Finish();
- if (HasMultipleFiles)
- {
- //export to MultipleFiles
- if (Directory.Exists(path) && !string.IsNullOrEmpty(FileName))
- {
- // desktop mode
- if (currentPage == 0)
- {
- // save first page in parent Stream
- Save(Stream);
- Stream.Position = 0;
- GeneratedStreams.Add(Stream);
- GeneratedFiles.Add(FileName);
- }
- else
- {
- // save all page after first in files
- Save(pageFileName);
- GeneratedFiles.Add(pageFileName);
- }
- }
- else if (string.IsNullOrEmpty(path))
- {
- if (currentPage == 0)
- {
- // save first page in parent Stream
- Save(Stream);
- Stream.Position = 0;
- GeneratedStreams.Add(Stream);
- GeneratedFiles.Add(FileName);
- }
- else
- {
- // server mode, save in internal stream collection
- MemoryStream pageStream = new MemoryStream();
- Save(pageStream);
- pageStream.Position = 0;
- GeneratedStreams.Add(pageStream);
- GeneratedFiles.Add(pageFileName);
- }
- }
- }
- // increment page number
- currentPage++;
- }
- /// <inheritdoc/>
- protected override void Finish()
- {
- if (!HasMultipleFiles)
- {
- Save(Stream);
- Stream.Position = 0;
- GeneratedFiles.Add(FileName);
- }
- GeneratedFiles.Clear();
- GeneratedStreams.Clear();
- }
- /// <inheritdoc/>
- protected override string GetFileFilter()
- {
- return new MyRes("FileFilters").Get("HpglFile");
- }
- #endregion
- /// <inheritdoc/>
- public override void Serialize(FRWriter writer)
- {
- base.Serialize(writer);
- writer.WriteBool("HasMultipleFiles", HasMultipleFiles);
- writer.WriteValue("FillMode", FillMode);
- }
- /// <summary>
- /// Export all report objects
- /// </summary>
- /// <param name="c"></param>
- public virtual void ExportObj(Base c)
- {
- if (c is ReportComponentBase && (c as ReportComponentBase).Exportable)
- {
- ReportComponentBase obj = c as ReportComponentBase;
- if (obj is CellularTextObject)
- obj = (obj as CellularTextObject).GetTable();
- if (obj is TableCell) return;
- else if (obj is TableBase)
- {
- TableBase table = obj as TableBase;
- if (table.ColumnCount > 0 && table.RowCount > 0)
- {
- using (TextObject tableback = new TextObject())
- {
- tableback.Border = table.Border;
- tableback.Fill = table.Fill;
- tableback.FillColor = table.FillColor;
- tableback.Left = table.AbsLeft;
- tableback.Top = table.AbsTop;
- float tableWidth = 0;
- float tableHeight = 0;
- for (int i = 0; i < table.ColumnCount; i++)
- tableWidth += table[i, 0].Width;
- for (int i = 0; i < table.RowCount; i++)
- tableHeight += table.Rows[i].Height;
- tableback.Width = (tableWidth < table.Width) ? tableWidth : table.Width;
- tableback.Height = tableHeight;
- //AddTextObject(tableback, false);
- // draw table border
- // AddBorder(tableback.Border, tableback.AbsLeft, tableback.AbsTop, tableback.Width, tableback.Height);
- }
- // draw cells
- AddTable(table);
- }
- }
- else if (obj is TextObject)
- AddTextObject(obj as TextObject, true);
- else if (obj is BandBase)
- AddBandObject(obj as BandBase);
- else if (obj is LineObject)
- AddLine(obj as LineObject);
- else if (obj is PolygonObject)
- AddPolygon(obj as PolygonObject);
- else if (obj is PolyLineObject)
- AddPolyLine(obj as PolyLineObject);
- else if (obj is ShapeObject)
- AddShape(obj as ShapeObject);
- //#if DOTNET_4
- // else if (obj is SVGObject)
- // AddBarcodeFromSvg(obj as BarcodeObject);
- //#endif
- else if (obj is BarcodeObject)
- AddBarcode(obj as BarcodeObject);
- //#if DOTNET_4
- // else if (obj is SVGObject)
- // AddSVGObject(c as SVGObject);
- //#endif
- // else
- // AddPictureObject(obj);
- }
- }
- private void AddBarcode(BarcodeObject barcodeObject)
- {
- using (var renderer = new HpglGraphicsRenderer(hpglDocument, fillMode, BarcodesGap))
- {
- bool error = false;
- string errorText = "";
- if (string.IsNullOrEmpty(barcodeObject.Text))
- {
- error = true;
- errorText = barcodeObject.NoDataText;
- }
- else
- try
- {
- // That line makes barcode not an invalid
- barcodeObject.UpdateAutoSize();
- }
- catch (Exception ex)
- {
- error = true;
- errorText = ex.Message;
- }
- if (!error)
- barcodeObject.Barcode.DrawBarcode(renderer, new RectangleF(barcodeObject.AbsLeft / Units.Millimeters,
- pageHeight - barcodeObject.AbsTop / Units.Millimeters, barcodeObject.Width / Units.Millimeters, barcodeObject.Height / Units.Millimeters));
- else
- {
- renderer.DrawString(errorText, DrawUtils.DefaultReportFont, Brushes.Red,
- new RectangleF(0, 0, barcodeObject.Width, barcodeObject.Height));
- }
- //barcodeObject.Barcode.DrawBarcode(renderer, new RectangleF(barcodeObject.AbsLeft,
- // barcodeObject.AbsTop, barcodeObject.Width, barcodeObject.Height));
- }
- }
- private string FloatToString(double flt)
- {
- return ExportUtils.FloatToString(flt);
- }
- }
- }
|