mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-10-19 15:43:20 +00:00

Previously, we were collapsing whitespace in Layout::TextNode and then passed the resulting string for further processing through ChunkIterator -> InlineLevelIterator -> InlineFormattingContext -> LineBuilder -> LineBoxFragment -> PaintableFragment. Our painting tree is where we deal with things like range offsets into the underlying text nodes, but since we modified the original string, the offsets were wrong. This changes the way we generate fragments: * Layout::TextNode no longer collapses whitespace as part of its stored "text for rendering", but moves this logic to ChunkIterator which splits up this text into separate views whenever whitespace needs to be collapsed. * Layout::LineBox now only extends the last fragment if its end offset is equal to the new fragment's start offset. Otherwise, there's a gap caused by collapsing whitespace and we need to generate a separate fragment for that in order to have a correct start offset. Some tests need new baselines because of the fixed start offsets. Fixes #566.
79 lines
3 KiB
C++
79 lines
3 KiB
C++
/*
|
|
* Copyright (c) 2018-2020, Andreas Kling <andreas@ladybird.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <LibGC/Ptr.h>
|
|
#include <LibGfx/Rect.h>
|
|
#include <LibGfx/TextLayout.h>
|
|
#include <LibWeb/CSS/Enums.h>
|
|
#include <LibWeb/PixelUnits.h>
|
|
|
|
namespace Web::Layout {
|
|
|
|
class LineBoxFragment {
|
|
friend class LineBox;
|
|
|
|
public:
|
|
LineBoxFragment(Node const& layout_node, size_t start, size_t length, CSSPixels inline_offset, CSSPixels block_offset, CSSPixels inline_length, CSSPixels block_length, CSSPixels border_box_top, CSS::Direction, CSS::WritingMode, RefPtr<Gfx::GlyphRun>);
|
|
|
|
Node const& layout_node() const { return m_layout_node; }
|
|
size_t start() const { return m_start; }
|
|
size_t length_in_code_units() const { return m_length_in_code_units; }
|
|
|
|
CSSPixelPoint offset() const;
|
|
CSSPixels inline_offset() const { return m_inline_offset; }
|
|
CSSPixels block_offset() const { return m_block_offset; }
|
|
void set_inline_offset(CSSPixels inline_offset) { m_inline_offset = inline_offset; }
|
|
void set_block_offset(CSSPixels block_offset) { m_block_offset = block_offset; }
|
|
|
|
// The baseline of a fragment is the number of pixels from the top to the text baseline.
|
|
void set_baseline(CSSPixels y) { m_baseline = y; }
|
|
CSSPixels baseline() const { return m_baseline; }
|
|
|
|
CSSPixelSize size() const;
|
|
CSSPixels width() const { return size().width(); }
|
|
CSSPixels height() const { return size().height(); }
|
|
CSSPixels inline_length() const { return m_inline_length; }
|
|
CSSPixels block_length() const { return m_block_length; }
|
|
void set_inline_length(CSSPixels inline_length) { m_inline_length = inline_length; }
|
|
void set_block_length(CSSPixels block_length) { m_block_length = block_length; }
|
|
|
|
CSSPixels border_box_top() const { return m_border_box_top; }
|
|
|
|
bool ends_in_whitespace() const;
|
|
bool is_justifiable_whitespace() const;
|
|
Utf16View text() const;
|
|
|
|
bool is_atomic_inline() const;
|
|
|
|
RefPtr<Gfx::GlyphRun> glyph_run() const { return m_glyph_run; }
|
|
CSS::WritingMode writing_mode() const { return m_writing_mode; }
|
|
void append_glyph_run(RefPtr<Gfx::GlyphRun> const&, CSSPixels run_width);
|
|
|
|
private:
|
|
CSS::Direction resolve_glyph_run_direction(Gfx::GlyphRun::TextType) const;
|
|
void append_glyph_run_ltr(RefPtr<Gfx::GlyphRun> const&, CSSPixels run_width);
|
|
void append_glyph_run_rtl(RefPtr<Gfx::GlyphRun> const&, CSSPixels run_width);
|
|
|
|
GC::Ref<Node const> m_layout_node;
|
|
size_t m_start { 0 };
|
|
size_t m_length_in_code_units { 0 };
|
|
CSSPixels m_inline_offset;
|
|
CSSPixels m_block_offset;
|
|
CSSPixels m_inline_length;
|
|
CSSPixels m_block_length;
|
|
CSSPixels m_border_box_top { 0 };
|
|
CSSPixels m_baseline { 0 };
|
|
CSS::Direction m_direction { CSS::Direction::Ltr };
|
|
CSS::WritingMode m_writing_mode { CSS::WritingMode::HorizontalTb };
|
|
|
|
RefPtr<Gfx::GlyphRun> m_glyph_run;
|
|
float m_insert_position { 0 };
|
|
CSS::Direction m_current_insert_direction { CSS::Direction::Ltr };
|
|
};
|
|
|
|
}
|