Skip to content

Commit

Permalink
Compute shrink-to-fit width for tables
Browse files Browse the repository at this point in the history
  • Loading branch information
AmaiKinono committed Sep 17, 2024
1 parent 9d36a83 commit 23dce0e
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 11 deletions.
7 changes: 4 additions & 3 deletions Source/Core/Layout/ContainerBox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "../../../Include/RmlUi/Core/ElementScroll.h"
#include "../../../Include/RmlUi/Core/Profiling.h"
#include "FlexFormattingContext.h"
#include "TableFormattingContext.h"
#include "FormattingContext.h"
#include "LayoutDetails.h"
#include <algorithm>
Expand Down Expand Up @@ -305,12 +306,12 @@ void TableWrapper::Close(const Vector2f content_overflow_size, const Box& box, f

float TableWrapper::GetShrinkToFitWidth() const
{
// We don't currently support shrink-to-fit layout of tables. However, for the trivial case of a fixed width, we
// simply return that.
// For the trivial case of a fixed width, we simply return that.
if (element->GetComputedValues().width().type == Style::Width::Type::Length)
return box.GetSize().x;

return 0.0f;
// Infer shrink-to-fit width from the intrinsic width of the element.
return TableFormattingContext::GetMaxContentSize(element).x;
}

String TableWrapper::DebugDumpTree(int depth) const
Expand Down
9 changes: 1 addition & 8 deletions Source/Core/Layout/LayoutDetails.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -257,13 +257,6 @@ float LayoutDetails::GetShrinkToFitWidth(Element* element, Vector2f containing_b
return box.GetSize().x;
}

// Currently we don't support shrink-to-fit width for tables. Just return a zero-sized width.
const Style::Display display = element->GetDisplay();
if (display == Style::Display::Table || display == Style::Display::InlineTable)
{
return 0.f;
}

// Use a large size for the box content width, so that it is practically unconstrained. This makes the formatting
// procedure act as if under a maximum content constraint. Children with percentage sizing values may be scaled
// based on this width (such as 'width' or 'margin'), if so, the layout is considered undefined like in CSS 2.
Expand Down Expand Up @@ -453,7 +446,7 @@ void LayoutDetails::BuildBoxWidth(Box& box, const ComputedValues& computed, floa
// See CSS 2.1 section 10.3.7 for when this should be applied.
const bool shrink_to_fit = !replaced_element &&
((computed.float_() != Style::Float::None) || (absolutely_positioned && inset_auto) ||
(computed.display() == Style::Display::InlineBlock || computed.display() == Style::Display::InlineFlex));
(computed.display() == Style::Display::InlineBlock || computed.display() == Style::Display::InlineFlex || computed.display() == Style::Display::InlineTable));

if (!shrink_to_fit)
{
Expand Down
31 changes: 31 additions & 0 deletions Source/Core/Layout/TableFormattingContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,37 @@ UniquePtr<LayoutBox> TableFormattingContext::Format(ContainerBox* parent_contain
return table_wrapper_box;
}

Vector2f TableFormattingContext::GetMaxContentSize(Element* element)
{
const Vector2f infinity(10000.0f, 10000.0f);
RootBox root(infinity);
auto table_wrapper_box = MakeUnique<TableWrapper>(element, &root);

TableFormattingContext context;
context.table_wrapper_box = table_wrapper_box.get();
context.element_table = element;
context.grid.Build(element, *table_wrapper_box);

Box& box = table_wrapper_box->GetBox();
LayoutDetails::BuildBox(box, infinity, element, BuildBoxMode::Block);
const Vector2f initial_content_size = box.GetSize();

context.table_auto_height = (initial_content_size.y < 0.0f);
context.table_content_offset = box.GetPosition();
context.table_initial_content_size = Vector2f(initial_content_size.x, Math::Max(0.0f, initial_content_size.y));
Math::SnapToPixelGrid(context.table_content_offset, context.table_initial_content_size);
context.table_max_size = Vector2f(FLT_MAX, FLT_MAX);

const ComputedValues& computed_table = element->GetComputedValues();
context.table_gap = Vector2f(ResolveValue(computed_table.column_gap(), context.table_initial_content_size.x));


Vector2f table_content_size, table_overflow_size;
float table_baseline = 0.f;
context.FormatTable(table_content_size, table_overflow_size, table_baseline);
return table_content_size;
}

void TableFormattingContext::FormatTable(Vector2f& table_content_size, Vector2f& table_overflow_size, float& table_baseline) const
{
// Defines the boxes for all columns in this table, one entry per table column (spanning columns will add multiple entries).
Expand Down
3 changes: 3 additions & 0 deletions Source/Core/Layout/TableFormattingContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ class TableFormattingContext final : public FormattingContext {
public:
static UniquePtr<LayoutBox> Format(ContainerBox* parent_container, Element* element, const Box* override_initial_box);

/// Conputes max-content size for a table element.
static Vector2f GetMaxContentSize(Element* element);

private:
TableFormattingContext() = default;

Expand Down

0 comments on commit 23dce0e

Please sign in to comment.