/// <summary> /// Draw the prepared box to a PDF page /// </summary> private Result <Nothing> RenderBox(XFont baseFont, KeyValuePair <string, DocumentBox> boxDef, double fx, double fy, XGraphics gfx, DocumentPage pageToRender, int pageIndex, int pageTotal) { var box = boxDef.Value !; var font = (box.Definition.BoxFontSize != null) ? GetFont(box.Definition.BoxFontSize.Value) : baseFont; // boxes are defined in terms of the background image pixels or existing PDF page, so we need to convert var boxWidth = box.Definition.Width * fx; var boxHeight = box.Definition.Height * fy; var space = new XRect(box.Definition.Left * fx, box.Definition.Top * fy, boxWidth, boxHeight); // Handle the special case of embedding an image if (box.BoxType == DocumentBoxType.EmbedJpegImage) { if (string.IsNullOrWhiteSpace(box.RenderContent !)) { return(Result.Success()); // empty data is considered OK } try { _loadingTimer.Start(); var jpegStream = _files.LoadUrl(box.RenderContent); if (jpegStream is null) { return(Result.Success()); // Embedded images are always considered optional } var img = XImage.FromStream(jpegStream); gfx.DrawImage(img, space); } catch (Exception ex) { Console.WriteLine(ex); // Nothing. Embedded images are always considered optional } finally { _loadingTimer.Stop(); } return(Result.Success()); } // Read data, or pick a special type var str = box.BoxType switch { DocumentBoxType.Normal => box.RenderContent, // For the special values, we might want to re-apply the display format DocumentBoxType.PageGenerationDate => TryApplyDisplayFormat(box, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")), DocumentBoxType.CurrentPageNumber => TryApplyDisplayFormat(box, (pageIndex + 1).ToString()), DocumentBoxType.TotalPageCount => TryApplyDisplayFormat(box, pageTotal.ToString()), DocumentBoxType.RepeatingPageNumber => TryApplyDisplayFormat(box, (pageToRender.RepeatIndex + 1).ToString()), DocumentBoxType.RepeatingPageTotalCount => TryApplyDisplayFormat(box, pageToRender.RepeatCount.ToString()), _ => box.RenderContent }; if (str == null) { return(Result.Success()); // empty data is considered OK } var align = MapAlignments(box.Definition); RenderTextInBox(font, gfx, box.Definition, fx, fy, str, space, align); return(Result.Success()); }