Serenity Operating System
at master 131 lines 5.6 kB view raw
1/* 2 * Copyright (c) 2020-2022, Andreas Kling <kling@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#pragma once 8 9#include <AK/OwnPtr.h> 10#include <LibWeb/Forward.h> 11#include <LibWeb/Layout/AvailableSpace.h> 12#include <LibWeb/Layout/LayoutState.h> 13 14namespace Web::Layout { 15 16class FormattingContext { 17public: 18 virtual ~FormattingContext(); 19 20 enum class Type { 21 Block, 22 Inline, 23 Flex, 24 Grid, 25 Table, 26 SVG, 27 }; 28 29 virtual void run(Box const&, LayoutMode, AvailableSpace const&) = 0; 30 31 // This function returns the automatic content height of the context's root box. 32 virtual CSSPixels automatic_content_width() const { return 0; } 33 34 // This function returns the automatic content height of the context's root box. 35 virtual CSSPixels automatic_content_height() const = 0; 36 37 Box const& context_box() const { return m_context_box; } 38 39 FormattingContext* parent() { return m_parent; } 40 FormattingContext const* parent() const { return m_parent; } 41 42 Type type() const { return m_type; } 43 bool is_block_formatting_context() const { return type() == Type::Block; } 44 45 virtual bool inhibits_floating() const { return false; } 46 47 static bool creates_block_formatting_context(Box const&); 48 49 static CSSPixels compute_width_for_replaced_element(LayoutState const&, ReplacedBox const&, AvailableSpace const&); 50 static CSSPixels compute_height_for_replaced_element(LayoutState const&, ReplacedBox const&, AvailableSpace const&); 51 52 OwnPtr<FormattingContext> create_independent_formatting_context_if_needed(LayoutState&, Box const& child_box); 53 54 virtual void parent_context_did_dimension_child_root_box() { } 55 56 CSSPixels calculate_min_content_width(Layout::Box const&) const; 57 CSSPixels calculate_max_content_width(Layout::Box const&) const; 58 CSSPixels calculate_min_content_height(Layout::Box const&, AvailableSize const& available_width) const; 59 CSSPixels calculate_max_content_height(Layout::Box const&, AvailableSize const& available_width) const; 60 61 CSSPixels calculate_fit_content_height(Layout::Box const&, AvailableSpace const&) const; 62 CSSPixels calculate_fit_content_width(Layout::Box const&, AvailableSpace const&) const; 63 64 CSS::Length calculate_inner_width(Layout::Box const&, AvailableSize const&, CSS::Size const& width) const; 65 CSS::Length calculate_inner_height(Layout::Box const&, AvailableSize const&, CSS::Size const& height) const; 66 67 virtual CSSPixels greatest_child_width(Box const&); 68 69 CSSPixels containing_block_width_for(Box const& box) const { return containing_block_width_for(box, m_state); } 70 CSSPixels containing_block_height_for(Box const& box) const { return containing_block_height_for(box, m_state); } 71 72 static CSSPixels containing_block_width_for(Box const&, LayoutState const&); 73 static CSSPixels containing_block_height_for(Box const&, LayoutState const&); 74 75 [[nodiscard]] CSSPixels calculate_stretch_fit_width(Box const&, AvailableSize const&) const; 76 [[nodiscard]] CSSPixels calculate_stretch_fit_height(Box const&, AvailableSize const&) const; 77 78 virtual bool can_determine_size_of_child() const { return false; } 79 virtual void determine_width_of_child(Box const&, AvailableSpace const&) { } 80 virtual void determine_height_of_child(Box const&, AvailableSpace const&) { } 81 82 virtual CSSPixelPoint calculate_static_position(Box const&) const; 83 bool can_skip_is_anonymous_text_run(Box&); 84 85protected: 86 FormattingContext(Type, LayoutState&, Box const&, FormattingContext* parent = nullptr); 87 88 static bool should_treat_width_as_auto(Box const&, AvailableSpace const&); 89 static bool should_treat_height_as_auto(Box const&, AvailableSpace const&); 90 91 OwnPtr<FormattingContext> layout_inside(Box const&, LayoutMode, AvailableSpace const&); 92 void compute_inset(Box const& box); 93 94 struct SpaceUsedByFloats { 95 CSSPixels left { 0 }; 96 CSSPixels right { 0 }; 97 }; 98 99 struct ShrinkToFitResult { 100 CSSPixels preferred_width { 0 }; 101 CSSPixels preferred_minimum_width { 0 }; 102 }; 103 104 static CSSPixels tentative_width_for_replaced_element(LayoutState const&, ReplacedBox const&, CSS::Size const& computed_width, AvailableSpace const&); 105 static CSSPixels tentative_height_for_replaced_element(LayoutState const&, ReplacedBox const&, CSS::Size const& computed_height, AvailableSpace const&); 106 CSSPixels compute_auto_height_for_block_formatting_context_root(Box const&) const; 107 108 ShrinkToFitResult calculate_shrink_to_fit_widths(Box const&); 109 110 void layout_absolutely_positioned_element(Box const&, AvailableSpace const&); 111 void compute_width_for_absolutely_positioned_element(Box const&, AvailableSpace const&); 112 void compute_width_for_absolutely_positioned_non_replaced_element(Box const&, AvailableSpace const&); 113 void compute_width_for_absolutely_positioned_replaced_element(ReplacedBox const&, AvailableSpace const&); 114 115 enum class BeforeOrAfterInsideLayout { 116 Before, 117 After, 118 }; 119 void compute_height_for_absolutely_positioned_element(Box const&, AvailableSpace const&, BeforeOrAfterInsideLayout); 120 void compute_height_for_absolutely_positioned_non_replaced_element(Box const&, AvailableSpace const&, BeforeOrAfterInsideLayout); 121 void compute_height_for_absolutely_positioned_replaced_element(ReplacedBox const&, AvailableSpace const&, BeforeOrAfterInsideLayout); 122 123 Type m_type {}; 124 125 FormattingContext* m_parent { nullptr }; 126 Box const& m_context_box; 127 128 LayoutState& m_state; 129}; 130 131}