コード例 #1
0
        private PageBacking LoadBackground(TemplateProject project, int sourcePageIndex, TemplatePage pageDef)
        {
            var backing = new PageBacking();

            if (_basePdf is null && !string.IsNullOrWhiteSpace(project.BasePdfFile !))
            {
                using var fileStream = _files.Load(project.BasePdfFile);
                _basePdf             = PdfReader.Open(fileStream, PdfDocumentOpenMode.Import); // Must use import mode to copy pages across
            }

            if (_basePdf != null)
            {
                backing.ExistingPage = _basePdf.Pages[sourcePageIndex];
            }

            if (!string.IsNullOrWhiteSpace(pageDef.BackgroundImage !))
            {
                using var fileStream    = _files.Load(project.BasePdfFile);
                backing.BackgroundImage = XImage.FromStream(fileStream);
            }

            return(backing);
        }
コード例 #2
0
        /// <summary>
        /// Render a prepared page into a PDF document
        /// </summary>
        private Result <Nothing> OutputPage(PdfDocument document, DocumentPage pageToRender, XFont font, PageBacking background, int pageIndex, int pageTotal)
        {
            var pageDef = pageToRender.Definition;

            // If we have a source PDF, and we aren't trying to render a blank page, then import the page
            var shouldCopyPdfPage = background.ExistingPage != null && pageDef.RenderBackground;
            var page = shouldCopyPdfPage ? document.AddPage(background.ExistingPage !) : document.AddPage(/*blank*/);

            // If dimensions are silly, reset to A4
            if (pageDef.WidthMillimetres < 10 || pageDef.WidthMillimetres > 1000)
            {
                pageDef.WidthMillimetres = 210;
            }
            if (pageDef.HeightMillimetres < 10 || pageDef.HeightMillimetres > 1000)
            {
                pageDef.HeightMillimetres = 297;
            }

            // Set the PDF page size (in points under the hood)
            page.Width  = XUnit.FromMillimeter(pageDef.WidthMillimetres);
            page.Height = XUnit.FromMillimeter(pageDef.HeightMillimetres);

            using var gfx = XGraphics.FromPdfPage(page);
            gfx.Save();

            if (shouldCopyPdfPage && background.ExistingPage !.Rotate != 0)
            {
                // Match visual-rotations on page
                var centre       = new XPoint(0, 0);
                var visualRotate = background.ExistingPage !.Rotate % 360; // degrees, spec says it should be a multiple of 90.
                var angle        = 360.0 - visualRotate;
                gfx.RotateAtTransform(angle, centre);

                switch (visualRotate)
                {
                case 90:
                    gfx.TranslateTransform(-page.Height.Point, 0);
                    break;

                case 180:
                    gfx.TranslateTransform(-page.Width.Point, -page.Height.Point);
                    break;

                case 270:
                    gfx.TranslateTransform(-page.Height.Point / 2.0, -page.Height.Point);     // this one is a guess, as I don't have an example
                    break;

                default:
                    throw new Exception("Unhandled visual rotation case");
                }

                if (background.ExistingPage.Orientation == PageOrientation.Landscape)
                {
                    (page.Width, page.Height) = (page.Height, page.Width);
                }
            }

            // Draw background at full page size
            _loadingTimer.Start();
            if (pageDef.RenderBackground && background.BackgroundImage != null)
            {
                var destRect = new XRect(0, 0, (float)page.Width.Point, (float)page.Height.Point);
                gfx.DrawImage(background.BackgroundImage, destRect);
            }
            _loadingTimer.Stop();

            // Do default scaling
            var fx = page.Width.Point / page.Width.Millimeter;
            var fy = page.Height.Point / page.Height.Millimeter;

            // If using an image, work out the bitmap -> page adjustment
            if (background.BackgroundImage != null)
            {
                fx = page.Width.Point / background.BackgroundImage.PixelWidth;
                fy = page.Height.Point / background.BackgroundImage.PixelHeight;
            }

            // Draw each box.
            foreach (var boxDef in pageToRender.DocumentBoxes)
            {
                var result = RenderBox(font, boxDef, fx, fy, gfx, pageToRender, pageIndex, pageTotal);
                if (result.IsFailure)
                {
                    return(result);
                }
            }

            gfx.Restore();

            return(Result.Success());
        }