LayoutTestExecutor.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  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.ProceedToNextRenderingPhase();
  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. pageContext.IncrementPageNumber();
  35. var spacePlan = container.Measure(pageSize);
  36. pageSizes.Add(spacePlan);
  37. if (spacePlan.Type == SpacePlanType.Wrap)
  38. {
  39. pageContext.DecrementPageNumber();
  40. canvas.EndDocument();
  41. return (pageSizes, true);
  42. }
  43. try
  44. {
  45. canvas.BeginPage(pageSize);
  46. container.Draw(pageSize);
  47. }
  48. catch (Exception exception)
  49. {
  50. canvas.EndDocument();
  51. throw new LayoutTestException("Exception occured during layout execution", exception);
  52. }
  53. canvas.EndPage();
  54. if (spacePlan.Type == SpacePlanType.FullRender)
  55. break;
  56. }
  57. return (pageSizes, false);
  58. }
  59. ICollection<LayoutTestResult.PageLayout> CollectMockInformation(ICollection<Size> pageSizes)
  60. {
  61. // mock cannot contain another mock, flat structure
  62. var mocks = container.ExtractElementsOfType<ElementMock>().Select(x => x.Value);
  63. return mocks
  64. .SelectMany(x => x.DrawingCommands)
  65. .GroupBy(x => x.PageNumber)
  66. .OrderBy(x => x.Key)
  67. .Select(x => new LayoutTestResult.PageLayout
  68. {
  69. RequiredArea = pageSizes.ElementAt(x.Key - 1),
  70. Mocks = x
  71. .Select(y => new LayoutTestResult.MockLayoutPosition
  72. {
  73. MockId = y.MockId,
  74. Size = y.Size,
  75. Position = y.Position
  76. })
  77. .ToList()
  78. })
  79. .ToList();
  80. }
  81. }
  82. }