TableFormattingContext.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /*
  2. * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #pragma once
  7. #include <AK/Forward.h>
  8. #include <LibWeb/Layout/FormattingContext.h>
  9. #include <LibWeb/Layout/TableWrapper.h>
  10. namespace Web::Layout {
  11. enum class TableDimension {
  12. Row,
  13. Column
  14. };
  15. class TableFormattingContext final : public FormattingContext {
  16. public:
  17. explicit TableFormattingContext(LayoutState&, Box const&, FormattingContext* parent);
  18. ~TableFormattingContext();
  19. virtual void run(Box const&, LayoutMode, AvailableSpace const&) override;
  20. virtual CSSPixels automatic_content_width() const override;
  21. virtual CSSPixels automatic_content_height() const override;
  22. Box const& table_box() const { return context_box(); }
  23. TableWrapper const& table_wrapper() const
  24. {
  25. return verify_cast<TableWrapper>(*table_box().containing_block());
  26. }
  27. static bool border_is_less_specific(const CSS::BorderData& a, const CSS::BorderData& b);
  28. private:
  29. CSSPixels run_caption_layout(LayoutMode, CSS::CaptionSide);
  30. CSSPixels compute_capmin();
  31. void calculate_row_column_grid(Box const&);
  32. void compute_cell_measures(AvailableSpace const& available_space);
  33. template<class RowOrColumn>
  34. void initialize_table_measures();
  35. template<class RowOrColumn>
  36. void compute_table_measures();
  37. void compute_table_width();
  38. void distribute_width_to_columns();
  39. void compute_table_height(LayoutMode layout_mode);
  40. void distribute_height_to_rows();
  41. void position_row_boxes();
  42. void position_cell_boxes();
  43. void border_conflict_resolution();
  44. CSSPixels border_spacing_horizontal() const;
  45. CSSPixels border_spacing_vertical() const;
  46. CSSPixels m_table_height { 0 };
  47. CSSPixels m_automatic_content_height { 0 };
  48. Optional<AvailableSpace> m_available_space;
  49. enum class SizeType {
  50. Percent,
  51. Pixel,
  52. Auto
  53. };
  54. struct Column {
  55. SizeType type { SizeType::Auto };
  56. CSSPixels left_offset { 0 };
  57. CSSPixels min_size { 0 };
  58. CSSPixels max_size { 0 };
  59. CSSPixels used_width { 0 };
  60. double percentage_width { 0 };
  61. // Store whether the column is constrained: https://www.w3.org/TR/css-tables-3/#constrainedness
  62. bool is_constrained { false };
  63. };
  64. struct Row {
  65. JS::NonnullGCPtr<Box const> box;
  66. CSSPixels base_height { 0 };
  67. CSSPixels reference_height { 0 };
  68. CSSPixels final_height { 0 };
  69. CSSPixels baseline { 0 };
  70. SizeType type { SizeType::Auto };
  71. CSSPixels min_size { 0 };
  72. CSSPixels max_size { 0 };
  73. double percentage_height { 0 };
  74. };
  75. struct Cell {
  76. JS::NonnullGCPtr<Box const> box;
  77. size_t column_index;
  78. size_t row_index;
  79. size_t column_span;
  80. size_t row_span;
  81. CSSPixels baseline { 0 };
  82. CSSPixels min_width { 0 };
  83. CSSPixels max_width { 0 };
  84. CSSPixels min_height { 0 };
  85. CSSPixels max_height { 0 };
  86. };
  87. // Accessors to enable direction-agnostic table measurement.
  88. template<class RowOrColumn>
  89. static size_t cell_span(Cell const& cell);
  90. template<class RowOrColumn>
  91. static size_t cell_index(Cell const& cell);
  92. template<class RowOrColumn>
  93. static CSSPixels cell_min_size(Cell const& cell);
  94. template<class RowOrColumn>
  95. static CSSPixels cell_max_size(Cell const& cell);
  96. template<class RowOrColumn>
  97. CSSPixels border_spacing();
  98. template<class RowOrColumn>
  99. Vector<RowOrColumn>& table_rows_or_columns();
  100. CSSPixels compute_row_content_height(Cell const& cell) const;
  101. enum class ConflictingSide {
  102. Top,
  103. Bottom,
  104. Left,
  105. Right,
  106. };
  107. struct ConflictingEdge {
  108. Node const* element;
  109. ConflictingSide side;
  110. };
  111. static const CSS::BorderData& border_data_conflicting_edge(ConflictingEdge const& conflicting_edge);
  112. class BorderConflictFinder {
  113. public:
  114. BorderConflictFinder(TableFormattingContext const* context);
  115. Vector<ConflictingEdge> conflicting_edges(Cell const&, ConflictingSide) const;
  116. private:
  117. void collect_conflicting_col_elements();
  118. Vector<Node const*> m_col_elements_by_index;
  119. TableFormattingContext const* m_context;
  120. };
  121. Vector<Cell> m_cells;
  122. Vector<Vector<Optional<Cell const&>>> m_cells_by_coordinate;
  123. Vector<Column> m_columns;
  124. Vector<Row> m_rows;
  125. };
  126. }