Plotting correct layout extent revisioned

1
rammi
3/13/2015 11:42 AM

In previous examples for printing layouts to PDF we only used the extent of the layout as the viewport to be printed. Although this is correct in many cases layouts are able to define other viewports. To be able to handle this we made some additions to CadLib in the latest release (4.0.36.36 from March 12, 2015). Now you can make use of two new methods in DxfLayout:

  • PlotInfo GetPlotInfo(bool invertY): if possible this method returns size and transformation information to plot the layout in its internally defined size.
  • PlotInfo GetPlotInfo(double paperWidth, double paperHeight, Rectangle2D printArea, bool autoRotate, bool invertY): if possible this method returns size and transformation information to plot the layout into the given printArea.
Here are two example methods which make use of the above methods to plot a layout to PDF either in its internally defined size or scaled to a given paper area:

C# Code:
        /// <summary>
        /// Create a PDF from a layout using the paper size defined in the layout.
        /// </summary>
        /// <param name="model">DXF model to write</param>
        /// <param name="layout">DXF layout to write</param>
        /// <param name="outfile">path of PDF output file</param>
        /// <param name="embedFonts">embed fonts into PDF?</param>
        /// <param name="lineWeight">default line weight in 100th of mm</param>
        /// <returns><c>true</c> if plotting was possible; <c>false</c> if plotting was not possible because the layout was invalid.</returns>
        public static bool PlotLayoutToPdf(DxfModel model, DxfLayout layout, string outfile, bool embedFonts, short lineWeight) {
            DxfLayout.PlotInfo plotInfo = layout.GetPlotInfo(false);
            if (plotInfo == null) {
                return false;
            }
            const double mmToInch = 1.0/25.4;
            const double mmToPdfPoints = mmToInch*PdfExporter.InchToPixel; 
            const double mmToPrintUnits = mmToInch*100;  // PaperSize measures in 100th of inch
            PaperSize paperSize = new PaperSize(layout.PaperSizeName,
                                                (int) System.Math.Round(plotInfo.PaperSize.X*mmToPrintUnits),
                                                (int) System.Math.Round(plotInfo.PaperSize.Y*mmToPrintUnits));
            
            using (Stream stream = File.Create(outfile)) {
                PdfExporter pdfGraphics = new PdfExporter(stream);
                pdfGraphics.EmbedFonts = embedFonts;
                GraphicsConfig config = new GraphicsConfig(Color.White, true);
                config.TryDrawingTextAsText = embedFonts;
                config.DefaultLineWeight = lineWeight;
                pdfGraphics.DrawPage(
                    model,
                    config, 
                    Transformation4D.Scaling(mmToPdfPoints) * plotInfo.ToPaperTransform,
                    mmToPdfPoints * plotInfo.Scaling,
                    layout,
                    null,
                    paperSize,
                    null);
                pdfGraphics.EndDocument();
            }
            return true;
        }

        /// <summary>
        /// Create a PDF from a layout scaled to a given paper.
        /// </summary>
        /// <param name="model">DXF model to write</param>
        /// <param name="layout">DXF layout to write</param>
        /// <param name="paperSize">Paper size to print to.</param>
        /// <param name="paperMargin">Empty margin of paper, in inch.</param>
        /// <param name="outfile">path of PDF output file.</param>
        /// <param name="embedFonts">embed fonts into PDF?</param>
        /// <param name="lineWeight">default line weight in 100th of mm</param>
        /// <returns><c>true</c> if plotting was possible; <c>false</c> if plotting was not possible because the layout was invalid.</returns>
        public static bool PlotScaledLayoutToPdf(DxfModel model, DxfLayout layout, PaperSize paperSize, 
                                                 double paperMargin, string outfile,
                                                 bool embedFonts, short lineWeight) {
            double paperWidthPdf = paperSize.Width/100.0*PdfExporter.InchToPixel;
            double paperHeightPdf = paperSize.Height/100.0*PdfExporter.InchToPixel;
            double paperMarginPdf = paperMargin*PdfExporter.InchToPixel;
            Rectangle2D printAreaPdf = new Rectangle2D(paperMarginPdf,
                                                       paperMarginPdf,
                                                       paperWidthPdf - paperMarginPdf,
                                                       paperHeightPdf - paperMarginPdf);
            DxfLayout.PlotInfo plotInfo = layout.GetPlotInfo(paperWidthPdf, paperHeightPdf, printAreaPdf, true, false);
            if (plotInfo == null) {
                return false;
            }
            using (Stream stream = File.Create(outfile)) {
                PdfExporter pdfGraphics = new PdfExporter(stream);
                pdfGraphics.EmbedFonts = embedFonts;
                GraphicsConfig config = new GraphicsConfig(Color.White, true);
                config.TryDrawingTextAsText = embedFonts;
                config.DefaultLineWeight = lineWeight;
                pdfGraphics.DrawPage(
                    model,
                    config,
                    plotInfo.ToPaperTransform,
                    plotInfo.Scaling,
                    layout,
                    null,
                    paperSize,
                    null);
                pdfGraphics.EndDocument();
            }
            return true;
        }

This methods will also work for model layouts. But you'll have to consider whether you indeed want to plot the part of the model defined by the layout or the complete model in its extents (see method WriteModelToPdf() provided in this thread). For the former you depend on the creator of your model, while the latter gives you defined results.

Please also note that the above just takes care of plotting the correct part of the layout to the PDF. Layouts might also define special renderings, switch off layers and other things which is not taken care of here.

- Rammi

1