|
|
@@ -41,7 +41,7 @@ namespace Rml {
|
|
|
|
|
|
// Creates a new block box for rendering a block element.
|
|
|
LayoutBlockBox::LayoutBlockBox(LayoutBlockBox* _parent, Element* _element, const Box& _box, float _min_height, float _max_height)
|
|
|
- : position(0), visible_outer_width(0), box(_box), min_height(_min_height), max_height(_max_height)
|
|
|
+ : position(0), box(_box), min_height(_min_height), max_height(_max_height)
|
|
|
{
|
|
|
RMLUI_ZoneScoped;
|
|
|
|
|
|
@@ -194,7 +194,7 @@ LayoutBlockBox::CloseResult LayoutBlockBox::Close()
|
|
|
box.SetContent(content_area);
|
|
|
}
|
|
|
|
|
|
- visible_outer_width = 0;
|
|
|
+ visible_overflow_size = Vector2f(0);
|
|
|
RMLUI_ASSERTMSG(!(context == INLINE && element), "The following assumes inline contexts do not represent a particular element.");
|
|
|
|
|
|
// Set the computed box on the element.
|
|
|
@@ -202,16 +202,12 @@ LayoutBlockBox::CloseResult LayoutBlockBox::Close()
|
|
|
{
|
|
|
// Calculate the dimensions of the box's *internal* content; this is the tightest-fitting box around all of the
|
|
|
// internal elements, plus this element's padding.
|
|
|
- Vector2f content_box(0, 0);
|
|
|
|
|
|
- for (size_t i = 0; i < block_boxes.size(); i++)
|
|
|
- {
|
|
|
- // TODO: Only if the containing block is not an ancestor of us (ie. we are the containing block?).
|
|
|
- content_box.x = Math::Max(content_box.x, block_boxes[i]->visible_outer_width);
|
|
|
- }
|
|
|
+ // Start with the inner content size, as set by the child blocks boxes or external formatting contexts.
|
|
|
+ Vector2f content_box = inner_content_size;
|
|
|
|
|
|
// Check how big our floated area is.
|
|
|
- Vector2f space_box = space->GetDimensions();
|
|
|
+ const Vector2f space_box = space->GetDimensions();
|
|
|
content_box.x = Math::Max(content_box.x, space_box.x);
|
|
|
|
|
|
// If our content is larger than our window, we can enable the horizontal scrollbar if
|
|
|
@@ -228,26 +224,32 @@ LayoutBlockBox::CloseResult LayoutBlockBox::Close()
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- content_box.x += (box.GetEdge(Box::PADDING, Box::LEFT) + box.GetEdge(Box::PADDING, Box::RIGHT));
|
|
|
-
|
|
|
- content_box.y = box_cursor;
|
|
|
+ content_box.y = Math::Max(content_box.y, box_cursor);
|
|
|
content_box.y = Math::Max(content_box.y, space_box.y);
|
|
|
if (!CatchVerticalOverflow(content_box.y))
|
|
|
return LAYOUT_SELF;
|
|
|
|
|
|
- content_box.y += (box.GetEdge(Box::PADDING, Box::TOP) + box.GetEdge(Box::PADDING, Box::BOTTOM));
|
|
|
+ const Vector2f padding_edges = Vector2f(
|
|
|
+ box.GetEdge(Box::PADDING, Box::LEFT) + box.GetEdge(Box::PADDING, Box::RIGHT),
|
|
|
+ box.GetEdge(Box::PADDING, Box::TOP) + box.GetEdge(Box::PADDING, Box::BOTTOM)
|
|
|
+ );
|
|
|
|
|
|
element->SetBox(box);
|
|
|
- element->SetContentBox(space->GetOffset(), content_box);
|
|
|
+ element->SetContentBox(space->GetOffset(), content_box + padding_edges);
|
|
|
|
|
|
- const float margin_width = box.GetSize(Box::MARGIN).x;
|
|
|
+ const Vector2f margin_size = box.GetSize(Box::MARGIN);
|
|
|
|
|
|
- // Set the visible outer width so that ancestors can catch any overflow produced by us. That is, hiding it or providing a scrolling mechanism.
|
|
|
+ // Set the visible overflow size so that ancestors can catch any overflow produced by us. That is, hiding it or providing a scrolling mechanism.
|
|
|
// If we catch our own overflow here, then just use the normal margin box as that will effectively remove the overflow from our ancestor's perspective.
|
|
|
if (overflow_x_property != Style::Overflow::Visible)
|
|
|
- visible_outer_width = margin_width;
|
|
|
+ visible_overflow_size.x = margin_size.x;
|
|
|
else
|
|
|
- visible_outer_width = Math::Max(margin_width, space->GetOffset().x + content_box.x + box.GetEdge(Box::MARGIN, Box::LEFT) + box.GetEdge(Box::MARGIN, Box::RIGHT));
|
|
|
+ visible_overflow_size.x = Math::Max(margin_size.x, content_box.x + box.GetEdge(Box::MARGIN, Box::LEFT) + box.GetEdge(Box::BORDER, Box::LEFT) + box.GetEdge(Box::PADDING, Box::LEFT));
|
|
|
+
|
|
|
+ if (overflow_y_property != Style::Overflow::Visible)
|
|
|
+ visible_overflow_size.y = margin_size.y;
|
|
|
+ else
|
|
|
+ visible_overflow_size.y = Math::Max(margin_size.y, content_box.y + box.GetEdge(Box::MARGIN, Box::TOP) + box.GetEdge(Box::BORDER, Box::TOP) + box.GetEdge(Box::PADDING, Box::TOP));
|
|
|
|
|
|
// Format any scrollbars which were enabled on this element.
|
|
|
element->GetElementScroll()->FormatScrollbars();
|
|
|
@@ -258,7 +260,7 @@ LayoutBlockBox::CloseResult LayoutBlockBox::Close()
|
|
|
for (size_t i = 0; i < line_boxes.size(); i++)
|
|
|
{
|
|
|
LayoutLineBox* line_box = line_boxes[i].get();
|
|
|
- visible_outer_width = Math::Max(visible_outer_width, line_box->GetBoxCursor());
|
|
|
+ visible_overflow_size.x = Math::Max(visible_overflow_size.x, line_box->GetBoxCursor());
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -321,7 +323,14 @@ LayoutBlockBox::CloseResult LayoutBlockBox::Close()
|
|
|
bool LayoutBlockBox::CloseBlockBox(LayoutBlockBox* child)
|
|
|
{
|
|
|
RMLUI_ASSERT(context == BLOCK);
|
|
|
- box_cursor = (child->GetPosition().y - child->box.GetEdge(Box::MARGIN, Box::TOP) - (box.GetPosition().y + position.y)) + child->GetBox().GetSize(Box::MARGIN).y;
|
|
|
+
|
|
|
+ const float child_position_y = child->GetPosition().y - child->box.GetEdge(Box::MARGIN, Box::TOP) - (box.GetPosition().y + position.y);
|
|
|
+
|
|
|
+ box_cursor = child_position_y + child->GetBox().GetSize(Box::MARGIN).y;
|
|
|
+
|
|
|
+ // Extend the inner content size. The vertical size can be larger than the box_cursor due to overflow.
|
|
|
+ inner_content_size.x = Math::Max(inner_content_size.x, child->visible_overflow_size.x);
|
|
|
+ inner_content_size.y = Math::Max(inner_content_size.y, child_position_y + child->visible_overflow_size.y);
|
|
|
|
|
|
return CatchVerticalOverflow();
|
|
|
}
|
|
|
@@ -634,6 +643,16 @@ float LayoutBlockBox::GetShrinkToFitWidth() const
|
|
|
return content_width;
|
|
|
}
|
|
|
|
|
|
+Vector2f LayoutBlockBox::GetVisibleOverflowSize() const
|
|
|
+{
|
|
|
+ return visible_overflow_size;
|
|
|
+}
|
|
|
+
|
|
|
+void LayoutBlockBox::ExtendInnerContentSize(Vector2f _inner_content_size)
|
|
|
+{
|
|
|
+ inner_content_size.x = Math::Max(inner_content_size.x, _inner_content_size.x);
|
|
|
+ inner_content_size.y = Math::Max(inner_content_size.y, _inner_content_size.y);
|
|
|
+}
|
|
|
|
|
|
// Returns the block box's element.
|
|
|
Element* LayoutBlockBox::GetElement() const
|
|
|
@@ -711,7 +730,7 @@ void LayoutBlockBox::PositionFloat(Element* element, float offset)
|
|
|
bool LayoutBlockBox::CatchVerticalOverflow(float cursor)
|
|
|
{
|
|
|
if (cursor == -1)
|
|
|
- cursor = box_cursor;
|
|
|
+ cursor = Math::Max(box_cursor, inner_content_size.y);
|
|
|
|
|
|
float box_height = box.GetSize().y;
|
|
|
if (box_height < 0)
|