Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 0 additions & 18 deletions Libraries/LibWeb/Layout/LayoutRustBridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1660,23 +1660,6 @@ bool can_replay_saved_abspos_layout_inputs_after_style_change(Box const& box)
return true;
}

static bool can_skip_is_anonymous_text_run(Box& box)
{
if (box.is_anonymous() && !box.is_generated_for_pseudo_element() && !box.first_child_of_type<BlockContainer>()) {
bool contains_only_white_space = true;
box.for_each_in_subtree([&](auto const& node) {
if (!is<TextNode>(node) || !static_cast<TextNode const&>(node).text().is_ascii_whitespace()) {
contains_only_white_space = false;
return TraversalDecision::Break;
}
return TraversalDecision::Continue;
});
if (contains_only_white_space)
return true;
}
return false;
}

RustFFI::FfiLayoutFcCallbacks LayoutRustBridge::formatting_context_callbacks()
{
static_assert(to_underlying(Painting::Paintable::ConflictingElementKind::Cell) == 0);
Expand Down Expand Up @@ -2112,7 +2095,6 @@ RustFFI::FfiLayoutFcCallbacks LayoutRustBridge::formatting_context_callbacks()
return;
}
box.set_default_scroll_shift(static_cast<Box*>(anchor)->make_weak_ptr(), horizontal, vertical); },
.can_skip_is_anonymous_text_run = [](void*, void* box) { return can_skip_is_anonymous_text_run(*static_cast<Box*>(box)); },
};
}

Expand Down
1 change: 1 addition & 0 deletions Libraries/LibWeb/Layout/TextNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,7 @@ void TextNode::sync_text_content_to_arena() const
view.has_ascii_storage() ? reinterpret_cast<u8 const*>(view.ascii_span().data()) : nullptr,
view.has_ascii_storage() ? nullptr : reinterpret_cast<u16 const*>(view.utf16_span().data()),
view.length_in_code_units(),
text().is_ascii_whitespace(),
Unicode::may_require_bidi_processing(view));
m_arena_text_content_in_sync = true;
}
Expand Down
5 changes: 1 addition & 4 deletions Libraries/LibWeb/Rust/src/layout/flex_formatting_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -790,10 +790,7 @@ impl<'pass> FlexFormattingContext<'pass> {
let next = self.callbacks.next_sibling(child);
let facts = self.facts(child);
if facts.is_box() {
// SAFETY: The callback only inspects the live layout subtree.
let skip = unsafe {
(self.callbacks.can_skip_is_anonymous_text_run)(self.callbacks.context, self.callbacks.shell(child))
};
let skip = self.callbacks.can_skip_is_anonymous_text_run(child);
// Skip any "out-of-flow" children
if !skip && !facts.is_absolutely_positioned() {
// Flex inhibits floating, so only absolute positioning is out of flow here.
Expand Down
20 changes: 19 additions & 1 deletion Libraries/LibWeb/Rust/src/layout/formatting_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4891,7 +4891,6 @@ pub struct FfiLayoutFcCallbacks {
pub anchor_function_fallback: unsafe extern "C" fn(*mut c_void, *const c_void) -> FfiAnchorFallbackFacts,
pub set_resolved_anchor_insets: unsafe extern "C" fn(*mut c_void, *mut c_void, FfiResolvedAnchorInsets),
pub set_default_scroll_shift: unsafe extern "C" fn(*mut c_void, *mut c_void, *mut c_void, bool, bool),
pub can_skip_is_anonymous_text_run: unsafe extern "C" fn(*mut c_void, *mut c_void) -> bool,
}

impl FfiLayoutFcCallbacks {
Expand All @@ -4917,6 +4916,25 @@ impl FfiLayoutFcCallbacks {
unsafe { &*std::ptr::from_ref(content) }
}

pub(crate) fn can_skip_is_anonymous_text_run(&self, node: Node) -> bool {
let data = self.node_data(node);
if !crate::layout::has_flag(data, NodeFlag::Anonymous) || data.generated_for != 0 {
return false;
}

let mut child = data.first_child;
while !child.is_invalid() {
let data = self.node_data(child);
if !crate::layout::kind_is_text(data.kind)
|| !self.text_content(child).untransformed_text_is_ascii_whitespace
{
return false;
}
child = data.next_sibling;
}
true
}

pub(crate) fn shell(&self, node: Node) -> *mut c_void {
let shell = self.node_data(node).shell;
assert!(!shell.is_null());
Expand Down
5 changes: 1 addition & 4 deletions Libraries/LibWeb/Rust/src/layout/grid_formatting_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1858,10 +1858,7 @@ impl<'pass> GridFormattingContext<'pass> {
let next = self.callbacks.next_sibling(child);
let box_facts = self.facts(child);
if box_facts.is_box() && !box_facts.is_absolutely_positioned() {
// SAFETY: The callback only inspects this live layout node.
let skip = unsafe {
(self.callbacks.can_skip_is_anonymous_text_run)(self.callbacks.context, self.callbacks.shell(child))
};
let skip = self.callbacks.can_skip_is_anonymous_text_run(child);
if !skip {
self.state.set_box_is_grid_item(&self.callbacks, child, true);
let child_grid = self.grid_facts_copy(child);
Expand Down
18 changes: 16 additions & 2 deletions Libraries/LibWeb/Rust/src/layout/layout_node_arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ struct SavedAbsposLayoutInputsSlot {
#[derive(Default)]
pub(crate) struct TextContent {
pub(crate) text: Vec<u16>,
pub(crate) untransformed_text_is_ascii_whitespace: bool,
pub(crate) may_require_bidi_processing: bool,
}

Expand Down Expand Up @@ -643,7 +644,13 @@ impl LayoutNodeArena {
}
}

pub(crate) fn set_text_content(&mut self, id: NodeSlotId, text: Vec<u16>, may_require_bidi_processing: bool) {
pub(crate) fn set_text_content(
&mut self,
id: NodeSlotId,
text: Vec<u16>,
untransformed_text_is_ascii_whitespace: bool,
may_require_bidi_processing: bool,
) {
self.assert_owner_thread();
self.data(id);
let index = id.slot_index() as usize;
Expand All @@ -654,6 +661,7 @@ impl LayoutNodeArena {
generation: id.generation(),
content: Some(Box::new(TextContent {
text,
untransformed_text_is_ascii_whitespace,
may_require_bidi_processing,
})),
};
Expand Down Expand Up @@ -813,6 +821,7 @@ pub unsafe extern "C" fn layout_arena_set_text_content(
ascii_text: *const u8,
utf16_text: *const u16,
length_in_code_units: usize,
untransformed_text_is_ascii_whitespace: bool,
may_require_bidi_processing: bool,
) {
abort_on_panic(|| {
Expand All @@ -834,7 +843,12 @@ pub unsafe extern "C" fn layout_arena_set_text_content(
};
// SAFETY: The C++ wrapper keeps the arena alive for this call and
// serializes all access on the document thread.
unsafe { &mut *arena.cast::<LayoutNodeArena>() }.set_text_content(id, text, may_require_bidi_processing);
unsafe { &mut *arena.cast::<LayoutNodeArena>() }.set_text_content(
id,
text,
untransformed_text_is_ascii_whitespace,
may_require_bidi_processing,
);
});
}

Expand Down
Loading