Michael Ragazzon 1 week ago
parent
commit
12abc300ce

+ 9 - 0
Include/RmlUi/Core/ElementText.h

@@ -75,6 +75,8 @@ public:
 	/// @param[in] line The contents of the line.
 	void AddLine(Vector2f line_position, String line);
 
+	void SubmitLayout(Element* offset_parent, Vector2f offset);
+
 	/// Prevents the element from dirtying its document's layout when its text is changed.
 	void SuppressAutoLayout();
 
@@ -101,6 +103,11 @@ public:
 	void Render(Element* parent, Vector2f translation);
 
 private:
+	struct Layout {
+		Element* offset_parent;
+		Vector2f offset;
+	};
+
 	// Prepares the font effects this element uses for its font.
 	bool UpdateFontEffects();
 
@@ -111,6 +118,8 @@ private:
 
 	String text;
 
+	Layout layout = {};
+
 	LineList lines;
 
 	struct TexturedGeometry {

+ 6 - 3
Source/Core/Element.cpp

@@ -224,7 +224,7 @@ void Element::Render()
 
 		// TODO(Michael): Offset is not correct. Should we make these nodes part of the stacking context?
 		for (ElementText* child : IterateChildren<ElementText>(true))
-			child->Render(this, GetAbsoluteOffset());
+			child->Render(this, absolute_offset);
 	}
 
 	// Render all elements in our local stacking context.
@@ -392,8 +392,11 @@ void Element::UpdateAbsoluteOffsetAndRenderBoxData()
 				offset_from_ancestors -= offset_parent->scroll_offset;
 
 			// Finally, there may be relatively positioned elements between ourself and our containing block, add their relative offsets as well.
-			for (Element* ancestor = GetParentElement(); ancestor && ancestor != offset_parent; ancestor = ancestor->GetParentElement())
-				offset_from_ancestors += ancestor->relative_offset_position;
+			for (Node* ancestor = GetParentNode(); ancestor && ancestor != offset_parent; ancestor = ancestor->GetParentNode())
+			{
+				if (Element* ancestor_element = AsIf<Element*>(ancestor))
+					offset_from_ancestors += ancestor_element->relative_offset_position;
+			}
 		}
 
 		const Vector2f relative_offset = relative_offset_base + relative_offset_position;

+ 16 - 0
Source/Core/ElementText.cpp

@@ -198,6 +198,16 @@ void ElementText::Render(Element* parent, Vector2f translation)
 		generated_decoration = decoration_property;
 	}
 
+	// TODO(Michael): This should not occur, assert instead.
+	if (!layout.offset_parent)
+		return;
+
+	// TODO(Michael): It's a bit more complicated. We should do the same as if calling GetAbsoluteOffset on this node.
+	// Except we don't have all of that data. See Element::UpdateAbsoluteOffsetAndRenderBoxData. Consider if we should
+	// have some kind of mix-in property, like SpatialNode that stores offset (including cached absolute offset, and
+	// parent node).
+	translation = layout.offset_parent->GetAbsoluteOffset() + layout.offset;
+
 	bool render = true;
 
 	// Do a visibility test against the scissor region to avoid unnecessary render calls. Instead of handling
@@ -381,6 +391,12 @@ void ElementText::AddLine(Vector2f line_position, String line)
 	geometry_dirty = true;
 }
 
+void ElementText::SubmitLayout(Element* offset_parent, Vector2f offset)
+{
+	layout.offset_parent = offset_parent;
+	layout.offset = offset;
+}
+
 void ElementText::SuppressAutoLayout()
 {
 	dirty_layout_on_change = false;

+ 8 - 3
Source/Core/Layout/InlineLevelBox.cpp

@@ -208,9 +208,10 @@ void InlineLevelBox_Text::Submit(const PlacedFragment& placed_fragment)
 
 	if (principal_box)
 	{
-		element_offset = placed_fragment.position;
-		// TODO(Michael): Where should we store the layout settings? Offset should really be part of that. Lines too? Or store fragments?
-		// text_element->SetOffset(placed_fragment.position, placed_fragment.offset_parent);
+		// element_offset = placed_fragment.position;
+		//  TODO(Michael): Where should we store the layout settings? Offset should really be part of that. Lines too? Or store fragments?
+		//  text_element->SetOffset(placed_fragment.position, placed_fragment.offset_parent);
+		text_element->SubmitLayout(placed_fragment.offset_parent, placed_fragment.position);
 		text_element->ClearLines();
 	}
 	else
@@ -218,6 +219,10 @@ void InlineLevelBox_Text::Submit(const PlacedFragment& placed_fragment)
 		line_offset = placed_fragment.position - element_offset;
 	}
 
+	// auto parent = text_element->GetParentElement();
+	// RMLUI_ASSERTMSG(parent == placed_fragment.offset_parent,
+	//	("Parent: " + parent->GetAddress() + " Offset parent: " + placed_fragment.offset_parent->GetAddress()).c_str());
+
 	text_element->AddLine(line_offset, std::move(fragments[fragment_index]));
 }