mirror of
https://github.com/RGBCube/serenity
synced 2025-05-24 15:05:07 +00:00

This patch combines a number of techniques to make inline content flow more correctly around floats: - During inline layout, BFC now lets LineBuilder decide the Y coordinate when inserting a new float. LineBuilder has more information about the currently accumulated line, and can make better breaking decisions. - When inserting a float on one side, and the top of the newly inserted float is below the bottommost float on the opposite side, we now reset the opposite side back to the start of that edge. This improves breaking behavior between opposite-side floats. - After inserting a float during inline layout, we now recalculate the available space on the line, but don't adjust X offsets of already existing fragments. This is handled by update_last_line() anyway, so it was pointless busywork. - When measuring whether a line can fit at a given Y coordinate, we now consider both the top and bottom Y values of the line. This fixes an issue where the bottom part of a line would bleed over other content (since we had only checked that the top Y coordinate of that line would fit.) There are some pretty brain-dead algorithms in here that we need to make smarter, but I didn't want to complicate this any further so I've left FIXMEs about them instead.
45 lines
1.4 KiB
C++
45 lines
1.4 KiB
C++
/*
|
|
* Copyright (c) 2020-2022, Andreas Kling <kling@serenityos.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <AK/Types.h>
|
|
#include <LibWeb/Forward.h>
|
|
#include <LibWeb/Layout/BlockContainer.h>
|
|
#include <LibWeb/Layout/FormattingContext.h>
|
|
|
|
namespace Web::Layout {
|
|
|
|
class InlineFormattingContext final : public FormattingContext {
|
|
public:
|
|
InlineFormattingContext(LayoutState&, BlockContainer const& containing_block, BlockFormattingContext& parent);
|
|
~InlineFormattingContext();
|
|
|
|
BlockFormattingContext& parent();
|
|
BlockFormattingContext const& parent() const;
|
|
|
|
BlockContainer const& containing_block() const { return static_cast<BlockContainer const&>(context_box()); }
|
|
|
|
virtual void run(Box const&, LayoutMode) override;
|
|
|
|
void dimension_box_on_line(Box const&, LayoutMode);
|
|
|
|
float leftmost_x_offset_at(float y) const;
|
|
float available_space_for_line(float y) const;
|
|
bool any_floats_intrude_at_y(float y) const;
|
|
bool can_fit_new_line_at_y(float y) const;
|
|
|
|
float effective_containing_block_width() const { return m_effective_containing_block_width; }
|
|
|
|
private:
|
|
void generate_line_boxes(LayoutMode);
|
|
void apply_justification_to_fragments(CSS::TextJustify, LineBox&, bool is_last_line);
|
|
|
|
LayoutState::UsedValues const& m_containing_block_state;
|
|
float m_effective_containing_block_width { 0 };
|
|
};
|
|
|
|
}
|