Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compute shrink-to-fit width for tables #673

Closed
wants to merge 1 commit into from
Closed
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
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