diff --git a/Include/RmlUi/Core/Element.h b/Include/RmlUi/Core/Element.h index 5ac545f44..915995c72 100644 --- a/Include/RmlUi/Core/Element.h +++ b/Include/RmlUi/Core/Element.h @@ -55,6 +55,7 @@ class ElementDefinition; class ElementDocument; class ElementScroll; class ElementStyle; +class LayoutBlockBox; class PropertiesIteratorView; class FontFaceHandleDefault; class PropertyDictionary; @@ -639,6 +640,7 @@ class RMLUICORE_API Element : public ScriptInterface, public EnableObserverPtrGetPosition() != Style::Position::Static) + // If we represent a positioned element, then we can now (as we've been sized) act as the containing block for all + // the absolutely-positioned elements of our descendants. + if (element->GetPosition() != Style::Position::Static) + { CloseAbsoluteElements(); + } + + // Set the baseline for inline-block elements to the baseline of the last line of the element. + // This is a special rule for inline-blocks (see CSS 2.1 §10.8.1). + if (element->GetDisplay() == Style::Display::InlineBlock) + { + bool found_baseline = false; + float baseline = 0; + + for (int i = (int)block_boxes.size() - 1; i >= 0; i--) + { + if (block_boxes[i]->context == INLINE) + { + const LineBoxList& line_boxes = block_boxes[i]->line_boxes; + for (int j = (int)line_boxes.size() - 1; j >= 0; j--) + { + found_baseline = line_boxes[j]->GetBaselineOfLastLine(baseline); + if (found_baseline) + break; + } + if (found_baseline) + break; + } + } + + if (found_baseline) + { + if (baseline < 0 && overflow_x_property != Style::Overflow::Visible || overflow_x_property != Style::Overflow::Visible) + { + baseline = 0; + } + + element->SetBaseline(baseline); + } + } } return OK; diff --git a/Source/Core/LayoutInlineBox.cpp b/Source/Core/LayoutInlineBox.cpp index 751ebbeef..825766674 100644 --- a/Source/Core/LayoutInlineBox.cpp +++ b/Source/Core/LayoutInlineBox.cpp @@ -47,8 +47,7 @@ LayoutInlineBox::LayoutInlineBox(Element* _element, const Box& _box) : position( width = 0; - // If this box has intrinsic dimensions, then we set our height to the total height of the element; otherwise, it - // is zero height. + // If this box has intrinsic dimensions, then we set our height to the total height of the element; otherwise, it is zero height. if (box.GetSize().y > 0) { height = box.GetSize(Box::MARGIN).y; diff --git a/Source/Core/LayoutLineBox.cpp b/Source/Core/LayoutLineBox.cpp index aa277368e..39851777a 100644 --- a/Source/Core/LayoutLineBox.cpp +++ b/Source/Core/LayoutLineBox.cpp @@ -369,6 +369,14 @@ float LayoutLineBox::GetBoxCursor() const return box_cursor; } +bool LayoutLineBox::GetBaselineOfLastLine(float& baseline) const +{ + if (inline_boxes.empty()) + return false; + baseline = inline_boxes.back()->GetBaseline(); + return true; +} + void* LayoutLineBox::operator new(size_t size) { return LayoutEngine::AllocateLayoutChunk(size); diff --git a/Source/Core/LayoutLineBox.h b/Source/Core/LayoutLineBox.h index c35f16d96..3e0466170 100644 --- a/Source/Core/LayoutLineBox.h +++ b/Source/Core/LayoutLineBox.h @@ -90,6 +90,8 @@ class LayoutLineBox float GetBoxCursor() const; + bool GetBaselineOfLastLine(float& baseline) const; + void* operator new(size_t size); void operator delete(void* chunk); diff --git a/Tests/Data/VisualTests/inline_block.rml b/Tests/Data/VisualTests/inline_block.rml index 13026f6c0..e2e5fe40c 100644 --- a/Tests/Data/VisualTests/inline_block.rml +++ b/Tests/Data/VisualTests/inline_block.rml @@ -9,9 +9,14 @@ color: #444; } .float { - float: left; color: #393; } + .left { + float: left; + } + .right { + float: right; + } .iblock { display: inline-block; color: #33c; @@ -29,7 +34,7 @@
Left filler text.
An inline-block.

A paragraph

Filler text.
Right filler text.

-
Left filler text.
An inline-block.
A float
Filler text.
Right filler text.
+
Left filler text.
An inline-block.
Float right
Float left
Filler text.
Right filler text.

Nesting inline-blocks:
A
B
C
diff --git a/Tests/Data/style.rcss b/Tests/Data/style.rcss index 6f48c1325..77e598ba2 100644 --- a/Tests/Data/style.rcss +++ b/Tests/Data/style.rcss @@ -1,4 +1,4 @@ -dl,dt,dd,ul,li,blockquote,address,h1,h2,h3,h4,h5,h6,p,pre,div { +dl,dt,dd,ul,li,blockquote,address,h1,h2,h3,h4,h5,h6,p,pre,div,section { display: block; }