LayoutTestExecutor.cs 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. using QuestPDF.Drawing;
  2. using QuestPDF.Drawing.Proxy;
  3. using QuestPDF.Elements;
  4. using QuestPDF.Helpers;
  5. using QuestPDF.Infrastructure;
  6. namespace QuestPDF.LayoutTests.TestEngine;
  7. internal static class LayoutTestExecutor
  8. {
  9. public static LayoutTestResult.DocumentLayout Execute(Size pageSize, Container container)
  10. {
  11. var (pageSizes, generatesInfiniteLayout) = GenerateDocument();
  12. return new LayoutTestResult.DocumentLayout
  13. {
  14. Pages = CollectMockInformation(pageSizes),
  15. GeneratesInfiniteLayout = generatesInfiniteLayout
  16. };
  17. (List<Size> pageSizes, bool generatesInfiniteLayout) GenerateDocument()
  18. {
  19. // inject dependencies
  20. var pageContext = new PageContext();
  21. pageContext.ResetPageNumber();
  22. var canvas = new PreviewerCanvas();
  23. container.InjectDependencies(pageContext, canvas);
  24. // distribute global state
  25. container.ApplyInheritedAndGlobalTexStyle(TextStyle.Default);
  26. container.ApplyContentDirection(ContentDirection.LeftToRight);
  27. container.ApplyDefaultImageConfiguration(DocumentSettings.Default.ImageRasterDpi, DocumentSettings.Default.ImageCompressionQuality, true);
  28. // render
  29. container.VisitChildren(x => (x as IStateResettable)?.ResetState());
  30. canvas.BeginDocument();
  31. var pageSizes = new List<Size>();
  32. while(true)
  33. {
  34. var spacePlan = container.Measure(pageSize);
  35. pageSizes.Add(spacePlan);
  36. if (spacePlan.Type == SpacePlanType.Wrap)
  37. {
  38. canvas.EndDocument();
  39. return (pageSizes, true);
  40. }
  41. try
  42. {
  43. canvas.BeginPage(pageSize);
  44. container.Draw(pageSize);
  45. pageContext.IncrementPageNumber();
  46. }
  47. catch (Exception exception)
  48. {
  49. canvas.EndDocument();
  50. throw new LayoutTestException("Exception occured during layout execution", exception);
  51. }
  52. canvas.EndPage();
  53. if (spacePlan.Type == SpacePlanType.FullRender)
  54. break;
  55. }
  56. return (pageSizes, false);
  57. }
  58. ICollection<LayoutTestResult.PageLayout> CollectMockInformation(ICollection<Size> pageSizes)
  59. {
  60. // mock cannot contain another mock, flat structure
  61. var mocks = container.ExtractElementsOfType<ElementMock>().Select(x => x.Value);
  62. return mocks
  63. .SelectMany(x => x.DrawingCommands)
  64. .GroupBy(x => x.PageNumber)
  65. .Select(x => new LayoutTestResult.PageLayout
  66. {
  67. RequiredArea = pageSizes.ElementAt(x.Key),
  68. Mocks = x
  69. .Select(y => new LayoutTestResult.MockLayoutPosition
  70. {
  71. MockId = y.MockId,
  72. Size = y.Size,
  73. Position = y.Position
  74. })
  75. .ToList()
  76. })
  77. .ToList();
  78. }
  79. }
  80. }