Browse Source

Compute all the properties!

Michael Ragazzon 6 years ago
parent
commit
c285bf99e9

+ 29 - 10
Include/Rocket/Core/ComputedValues.h

@@ -65,8 +65,10 @@ enum class Float { None, Left, Right };
 enum class Clear { None, Left, Right, Both };
 
 struct VerticalAlign {
-	enum Type { Baseline, Middle, Sub, Super, TextTop, TextBottom, Top, Bottom, Length } type = Baseline;
-	float value = 0; // For length type
+	enum Type { Baseline, Middle, Sub, Super, TextTop, TextBottom, Top, Bottom, Length } type;
+	float value; // For length type
+	VerticalAlign(Type type = Baseline) : type(type), value(0) {}
+	VerticalAlign(float value) : type(Length), value(value) {}
 };
 
 
@@ -89,6 +91,17 @@ enum class TabIndex { None, Auto };
 enum class Focus { None, Auto };
 enum class PointerEvents { None, Auto };
 
+enum class OriginX { Left, Center, Right };
+enum class OriginY { Top, Center, Bottom };
+
+struct LineHeight {
+	float value = 12.f*1.2f; // The computed value (length)
+	enum InheritType { Number, Length } inherit_type = Number;
+	float inherit_value = 1.2f;
+	LineHeight() {}
+	LineHeight(float value, InheritType inherit_type, float inherit_value) : value(value), inherit_type(inherit_type), inherit_value(inherit_value) {}
+};
+
 // A computed value is a value resolved as far as possible :before: updating layout. See CSS specs for details of each property.
 struct ComputedValues
 {
@@ -100,9 +113,12 @@ struct ComputedValues
 	Display display = Display::Inline;
 	Position position = Position::Static;
 
-	LengthPercentageAuto top{ LengthPercentageAuto::Auto }, right{ LengthPercentageAuto::Auto }, bottom{ LengthPercentageAuto::Auto }, left{ LengthPercentageAuto::Auto };
+	LengthPercentageAuto top{ LengthPercentageAuto::Auto };
+	LengthPercentageAuto right{ LengthPercentageAuto::Auto };
+	LengthPercentageAuto bottom{ LengthPercentageAuto::Auto };
+	LengthPercentageAuto left{ LengthPercentageAuto::Auto };
 
-	Float _float = Float::None;
+	Float float_ = Float::None;
 	Clear clear = Clear::None;
 
 	NumberAuto z_index = { NumberAuto::Auto };
@@ -112,7 +128,7 @@ struct ComputedValues
 	LengthPercentageAuto height = { LengthPercentageAuto::Auto };
 	LengthPercentage min_height, max_height;
 
-	float line_height = 1.2f;
+	LineHeight line_height;
 	VerticalAlign vertical_align;
 
 	Overflow overflow_x = Overflow::Visible, overflow_y = Overflow::Visible;
@@ -145,13 +161,16 @@ struct ComputedValues
 	PointerEvents pointer_events = PointerEvents::Auto;
 
 	float perspective = 0;
-	float perspective_origin_x = 0.5f, perspective_origin_y = 0.5f; // Relative
+	LengthPercentage perspective_origin_x = { LengthPercentage::Percentage, 50.f };
+	LengthPercentage perspective_origin_y = { LengthPercentage::Percentage, 50.f };
 
-	String transform;
-	float transform_origin_x = 0.5f, transform_origin_y = 0.5f, transform_origin_z = 0.f;
+	TransformRef transform;
+	LengthPercentage transform_origin_x = { LengthPercentage::Percentage, 50.f };
+	LengthPercentage transform_origin_y = { LengthPercentage::Percentage, 50.f };
+	float transform_origin_z = 0.0f;
 
-	String transition; // empty is same as "none"
-	String animation;  // empty is same as "none"
+	TransitionList transition;
+	AnimationList animation;
 };
 }
 

+ 0 - 5
Include/Rocket/Core/StyleSheetKeywords.h

@@ -40,11 +40,6 @@ const int FLOAT_NONE = 0;
 const int FLOAT_LEFT = 1;
 const int FLOAT_RIGHT = 2;
 
-const int CLEAR_NONE = 0;
-const int CLEAR_LEFT = 1;
-const int CLEAR_RIGHT = 2;
-const int CLEAR_BOTH = 3;
-
 const int DISPLAY_NONE = 0;
 const int DISPLAY_BLOCK = 1;
 const int DISPLAY_INLINE = 2;

+ 6 - 5
Source/Core/ElementBorder.cpp

@@ -88,15 +88,16 @@ void ElementBorder::GenerateBorder()
 	{
 		Vertex* raw_vertices = &vertices[0];
 		int* raw_indices = &indices[0];
+		const ComputedValues& computed = element->GetComputedValues();
 
 		Colourb border_colours[4];
-		border_colours[0] = element->GetProperty(BORDER_TOP_COLOR)->value.Get< Colourb >();
-		border_colours[1] = element->GetProperty(BORDER_RIGHT_COLOR)->value.Get< Colourb >();
-		border_colours[2] = element->GetProperty(BORDER_BOTTOM_COLOR)->value.Get< Colourb >();
-		border_colours[3] = element->GetProperty(BORDER_LEFT_COLOR)->value.Get< Colourb >();
+		border_colours[0] = computed.border_top_color;
+		border_colours[1] = computed.border_right_color;
+		border_colours[2] = computed.border_bottom_color;
+		border_colours[3] = computed.border_left_color;
 
 		// Apply opacity to the border
-		float opacity = element->GetProperty<float>(OPACITY);
+		float opacity = computed.opacity;
 		for(int i = 0; i < 4; ++i) {
 			border_colours[i].alpha = (byte)(opacity * (float)border_colours[i].alpha);
 		}

+ 2 - 2
Source/Core/ElementDocument.cpp

@@ -434,7 +434,7 @@ void ElementDocument::ProcessEvent(Event& event)
 		{
 			Element* focus_node = GetFocusLeafNode();
 
-			if (focus_node && focus_node->GetProperty<int>(TAB_INDEX) == TAB_INDEX_AUTO)
+			if (focus_node && focus_node->GetComputedValues().tab_index == Style::TabIndex::Auto)
 			{
 				focus_node->Click();
 			}
@@ -519,7 +519,7 @@ bool ElementDocument::SearchFocusSubtree(Element* element, bool forward)
 	}
 
 	// Check if this is the node we're looking for
-	if (element->GetProperty<int>(TAB_INDEX) == TAB_INDEX_AUTO)
+	if (element->GetComputedValues().tab_index == Style::TabIndex::Auto)
 	{
 		element->Focus();
 		element->ScrollIntoView(false);

+ 4 - 2
Source/Core/ElementImage.cpp

@@ -205,8 +205,10 @@ void ElementImage::GenerateGeometry()
 		texcoords[1] = Vector2f(1, 1);
 	}
 
-    float opacity = GetProperty<float>(OPACITY);
-	Colourb quad_colour = GetProperty<Colourb>(IMAGE_COLOR);
+	const ComputedValues& computed = GetComputedValues();
+
+	float opacity = computed.opacity;
+	Colourb quad_colour = computed.image_color;
     quad_colour.alpha = (byte)(opacity * (float)quad_colour.alpha);
 	
 	Vector2f quad_size = GetBox().GetSize(Rocket::Core::Box::CONTENT).Round();

+ 225 - 41
Source/Core/ElementStyle.cpp

@@ -1189,6 +1189,49 @@ static inline Style::Clip ComputeClip(const Property* property)
 	return Style::Clip::Auto;
 }
 
+static inline Style::LineHeight ComputeLineHeight(const Property* property, float font_size, float document_font_size, float dp_ratio, float pixels_per_inch)
+{
+	if (property->unit & Property::LENGTH)
+	{
+		float value = ComputeLength(property, font_size, document_font_size, dp_ratio, pixels_per_inch);
+		return Style::LineHeight(value, Style::LineHeight::Length, value);
+	}
+
+	float scale_factor = 1.0f;
+
+	switch (property->unit)
+	{
+	case Property::NUMBER:
+		scale_factor = property->value.Get< float >();
+		break;
+	case Property::PERCENT:
+		scale_factor = property->value.Get< float >() * 0.01f;
+		break;
+	default:
+		ROCKET_ERRORMSG("Invalid unit for line-height");
+	}
+
+	float value = font_size * scale_factor;
+	return Style::LineHeight(value, Style::LineHeight::Number, scale_factor);
+}
+
+
+static inline Style::VerticalAlign ComputeVerticalAlign(const Property* property, float line_height, float font_size, float document_font_size, float dp_ratio, float pixels_per_inch)
+{
+	if (property->unit & Property::LENGTH)
+	{
+		float value = ComputeLength(property, font_size, document_font_size, dp_ratio, pixels_per_inch);
+		return Style::VerticalAlign(value);
+	}
+	else if (property->unit & Property::PERCENT)
+	{
+		return Style::VerticalAlign(property->Get<float>() * line_height);
+	}
+
+	ROCKET_ASSERT(property->unit & Property::KEYWORD);
+	return Style::VerticalAlign((Style::VerticalAlign::Type)property->Get<int>());
+}
+
 static inline LengthPercentage ComputeLengthPercentage(const Property* property, float font_size, float document_font_size, float dp_ratio, float pixels_per_inch)
 {
 	if (property->unit & Property::PERCENT)
@@ -1209,14 +1252,36 @@ static inline LengthPercentageAuto ComputeLengthPercentageAuto(const Property* p
 	return LengthPercentageAuto(LengthPercentageAuto::Length, ComputeLength(property, font_size, document_font_size, dp_ratio, pixels_per_inch));
 }
 
+static inline LengthPercentage ComputeOrigin(const Property* property, float font_size, float document_font_size, float dp_ratio, float pixels_per_inch)
+{
+	using namespace Style;
+	static_assert((int)OriginX::Left == (int)OriginY::Top && (int)OriginX::Center == (int)OriginY::Center && (int)OriginX::Right == (int)OriginY::Bottom, "");
+
+	if (property->unit & Property::KEYWORD)
+	{
+		float percent = 0.0f;
+		OriginX origin = (OriginX)property->Get<int>();
+		switch (origin)
+		{
+		case OriginX::Left: percent = 0.0f; break;
+		case OriginX::Center: percent = 50.0f; break;
+		case OriginX::Right: percent = 100.f; break;
+		}
+		return LengthPercentage(LengthPercentage::Percentage, percent);
+	}
+	else if (property->unit & Property::PERCENT)
+		return LengthPercentage(LengthPercentage::Percentage, property->Get<float>());
+
+	return LengthPercentage(LengthPercentage::Length, ComputeLength(property, font_size, document_font_size, dp_ratio, pixels_per_inch));
+}
+
+
+
 
 // Must be called in correct order, from document root to children elements.
 void ElementStyle::ComputeValues(Style::ComputedValues& values, const Style::ComputedValues* parent_values, const Style::ComputedValues* document_values, float dp_ratio, float pixels_per_inch)
 {
-	// TODO: Iterate through dirty values, and compute corresponding properties.
-	// Important: Always do font-size first if dirty, because of em-relative values.
-	// Whenever the font-size changes, we need to dirty all properties making use of em!
-
+	// Always do font-size first if dirty, because of em-relative values
 	if (auto p = GetLocalProperty(FONT_SIZE))
 		values.font_size = ComputeFontsize(*p, values, parent_values, document_values, dp_ratio, pixels_per_inch);
 	else if (parent_values)
@@ -1225,18 +1290,45 @@ void ElementStyle::ComputeValues(Style::ComputedValues& values, const Style::Com
 	const float font_size = values.font_size;
 	const float document_font_size = (document_values ? document_values->font_size : DefaultComputedValues.font_size);
 
+	// Since vertical-align depends on line-height we compute this before iteration
+	if (auto p = GetLocalProperty(LINE_HEIGHT))
+	{
+		values.line_height = ComputeLineHeight(p, font_size, document_font_size, dp_ratio, pixels_per_inch);
+	}
+	else if (parent_values)
+	{
+		// Line height has a special inheritance case for numbers/percent: they inherit them directly instead of computed length, but for lengths, they inherit the length.
+		// See CSS specs for details. Percent is already converted to number.
+		if (parent_values->line_height.inherit_type == Style::LineHeight::Number)
+			values.line_height = Style::LineHeight(font_size * parent_values->line_height.inherit_value, Style::LineHeight::Number, parent_values->line_height.inherit_value);
+		else
+			values.line_height = parent_values->line_height;
+	}
+
+
 	if (parent_values)
 	{
-		// Properties that are inherited if not defined locally
+		// Inherited properties are copied here, but may be overwritten below by locally defined properties
+		// Line-height and font-size are computed above
+		values.clip = parent_values->clip;
+		
+		values.color = parent_values->color;
+		values.opacity = parent_values->opacity;
+
 		values.font_family = parent_values->font_family;
 		values.font_charset = parent_values->font_charset;
 		values.font_style = parent_values->font_style;
 		values.font_weight = parent_values->font_weight;
+
+		values.text_align = parent_values->text_align;
 		values.text_decoration = parent_values->text_decoration;
-		values.clip = parent_values->clip;
-		values.opacity = parent_values->opacity;
-		values.color = parent_values->color;
+		values.text_transform = parent_values->text_transform;
+		values.white_space = parent_values->white_space;
+
+		values.cursor = parent_values->cursor;
 		values.focus = parent_values->focus;
+
+		values.pointer_events = parent_values->pointer_events;
 	}
 
 
@@ -1246,39 +1338,13 @@ void ElementStyle::ComputeValues(Style::ComputedValues& values, const Style::Com
 
 	while (IterateProperties(index, name, p))
 	{
-		// @performance: Can use a switch-case with constexpr hashing function
-		if (name == FONT_FAMILY)
-			values.font_family = p->Get<String>();
-		else if (name == FONT_CHARSET)
-			values.font_charset = p->Get<String>();
-		else if (name == FONT_STYLE)
-			values.font_style = (Style::FontStyle)p->Get< int >();
-		else if (name == FONT_WEIGHT)
-			values.font_weight = (Style::FontWeight)p->Get< int >();
-
-		else if (name == TEXT_DECORATION)
-			values.text_decoration = (Style::TextDecoration)p->Get< int >();
-
-		else if (name == OVERFLOW_X)
-			values.overflow_x = (Style::Overflow)p->Get< int >();
-		else if (name == OVERFLOW_Y)
-			values.overflow_y = (Style::Overflow)p->Get< int >();
-		else if (name == CLIP)
-			values.clip = ComputeClip(p);
-		else if (name == VISIBILITY)
-			values.visibility = (Style::Visibility)p->Get< int >();
-
-		else if (name == OPACITY)
-			values.opacity = p->Get<float>();
+		using namespace Style;
 
-		else if (name == BACKGROUND_COLOR)
-			values.background_color = p->Get<Colourb>();
-		else if (name == IMAGE_COLOR)
-			values.image_color = p->Get<Colourb>();
-		else if (name == COLOR)
-			values.color = p->Get<Colourb>();
+		// @performance: Can use a switch-case with constexpr hashing function
+		// Or even better: a PropertyId enum, but the problem is custom properties such as decorators. We may want to redo the decleration of these perhaps...
+		// @performance: Compare to the list of actually changed properties, skip if not inside it
 
-		else if (name == MARGIN_TOP)
+		if (name == MARGIN_TOP)
 			values.margin_top = ComputeLengthPercentageAuto(p, font_size, document_font_size, dp_ratio, pixels_per_inch);
 		else if (name == MARGIN_RIGHT)
 			values.margin_right = ComputeLengthPercentageAuto(p, font_size, document_font_size, dp_ratio, pixels_per_inch);
@@ -1305,11 +1371,129 @@ void ElementStyle::ComputeValues(Style::ComputedValues& values, const Style::Com
 		else if (name == BORDER_LEFT_WIDTH)
 			values.border_top_width = ComputeLength(p, font_size, document_font_size, dp_ratio, pixels_per_inch);
 
-		else if (name == FOCUS)
-			values.focus = (Style::Focus)p->Get<int>();
+		else if (name == BORDER_TOP_COLOR)
+			values.border_top_color = p->Get<Colourb>();
+		else if (name == BORDER_RIGHT_COLOR)
+			values.border_right_color = p->Get<Colourb>();
+		else if (name == BORDER_BOTTOM_COLOR)
+			values.border_bottom_color = p->Get<Colourb>();
+		else if (name == BORDER_LEFT_COLOR)
+			values.border_left_color = p->Get<Colourb>();
+
+		else if (name == DISPLAY)
+			values.display = (Display)p->Get<int>();
+		else if (name == POSITION)
+			values.position = (Position)p->Get<int>();
+
+		else if (name == TOP)
+			values.top = ComputeLengthPercentageAuto(p, font_size, document_font_size, dp_ratio, pixels_per_inch);
+		else if (name == RIGHT)
+			values.right = ComputeLengthPercentageAuto(p, font_size, document_font_size, dp_ratio, pixels_per_inch);
+		else if (name == BOTTOM)
+			values.bottom = ComputeLengthPercentageAuto(p, font_size, document_font_size, dp_ratio, pixels_per_inch);
+		else if (name == LEFT)
+			values.left = ComputeLengthPercentageAuto(p, font_size, document_font_size, dp_ratio, pixels_per_inch);
+
+		else if (name == FLOAT)
+			values.float_ = (Float)p->Get<int>();
+		else if (name == CLEAR)
+			values.clear = (Clear)p->Get<int>();
+
 		else if (name == Z_INDEX)
 			values.z_index = (p->unit == Property::KEYWORD ? NumberAuto(NumberAuto::Auto) : NumberAuto(NumberAuto::Number, p->Get<float>()));
 
+		else if (name == WIDTH)
+			values.width = ComputeLengthPercentageAuto(p, font_size, document_font_size, dp_ratio, pixels_per_inch);
+		else if (name == MIN_WIDTH)
+			values.min_width = ComputeLengthPercentage(p, font_size, document_font_size, dp_ratio, pixels_per_inch);
+		else if (name == MAX_WIDTH)
+			values.max_width = ComputeLengthPercentage(p, font_size, document_font_size, dp_ratio, pixels_per_inch);
+
+		else if (name == HEIGHT)
+			values.height = ComputeLengthPercentageAuto(p, font_size, document_font_size, dp_ratio, pixels_per_inch);
+		else if (name == MIN_HEIGHT)
+			values.min_height = ComputeLengthPercentage(p, font_size, document_font_size, dp_ratio, pixels_per_inch);
+		else if (name == MAX_HEIGHT)
+			values.max_height = ComputeLengthPercentage(p, font_size, document_font_size, dp_ratio, pixels_per_inch);
+
+		// (Line-height computed above)
+		else if (name == VERTICAL_ALIGN)
+			values.vertical_align = ComputeVerticalAlign(p, values.line_height.value, font_size, document_font_size, dp_ratio, pixels_per_inch);
+
+		else if (name == OVERFLOW_X)
+			values.overflow_x = (Overflow)p->Get< int >();
+		else if (name == OVERFLOW_Y)
+			values.overflow_y = (Overflow)p->Get< int >();
+		else if (name == CLIP)
+			values.clip = ComputeClip(p);
+		else if (name == VISIBILITY)
+			values.visibility = (Visibility)p->Get< int >();
+
+
+		else if (name == BACKGROUND_COLOR)
+			values.background_color = p->Get<Colourb>();
+		else if (name == COLOR)
+			values.color = p->Get<Colourb>();
+		else if (name == IMAGE_COLOR)
+			values.image_color = p->Get<Colourb>();
+		else if (name == OPACITY)
+			values.opacity = p->Get<float>();
+
+
+		else if (name == FONT_FAMILY)
+			values.font_family = p->Get<String>();
+		else if (name == FONT_CHARSET)
+			values.font_charset = p->Get<String>();
+		else if (name == FONT_STYLE)
+			values.font_style = (FontStyle)p->Get< int >();
+		else if (name == FONT_WEIGHT)
+			values.font_weight = (FontWeight)p->Get< int >();
+		// (font-size computed above)
+
+		else if (name == TEXT_ALIGN)
+			values.text_align = (TextAlign)p->Get< int >();
+		else if (name == TEXT_DECORATION)
+			values.text_decoration = (TextDecoration)p->Get< int >();
+		else if (name == TEXT_TRANSFORM)
+			values.text_transform = (TextTransform)p->Get< int >();
+		else if (name == WHITE_SPACE)
+			values.white_space = (WhiteSpace)p->Get< int >();
+
+		else if (name == CURSOR)
+			values.cursor = p->Get< String >();
+
+		else if (name == DRAG)
+			values.drag = (Drag)p->Get< int >();
+		else if (name == TAB_INDEX)
+			values.tab_index = (TabIndex)p->Get< int >();
+		else if (name == FOCUS)
+			values.focus = (Focus)p->Get<int>();
+		else if (name == SCROLLBAR_MARGIN)
+			values.scrollbar_margin = ComputeLength(p, font_size, document_font_size, dp_ratio, pixels_per_inch);
+		else if (name == POINTER_EVENTS)
+			values.pointer_events = (PointerEvents)p->Get<int>();
+
+		else if (name == PERSPECTIVE)
+			values.perspective = ComputeLength(p, font_size, document_font_size, dp_ratio, pixels_per_inch);
+		else if (name == PERSPECTIVE_ORIGIN_X)
+			values.perspective_origin_x = ComputeOrigin(p, font_size, document_font_size, dp_ratio, pixels_per_inch);
+		else if (name == PERSPECTIVE_ORIGIN_Y)
+			values.perspective_origin_y = ComputeOrigin(p, font_size, document_font_size, dp_ratio, pixels_per_inch);
+
+		else if (name == TRANSFORM)
+			values.transform = p->Get<TransformRef>();
+		else if(name == TRANSFORM_ORIGIN_X)
+			values.transform_origin_x = ComputeOrigin(p, font_size, document_font_size, dp_ratio, pixels_per_inch);
+		else if (name == TRANSFORM_ORIGIN_Y)
+			values.transform_origin_y = ComputeOrigin(p, font_size, document_font_size, dp_ratio, pixels_per_inch);
+		else if (name == TRANSFORM_ORIGIN_Z)
+			values.transform_origin_z = ComputeLength(p, font_size, document_font_size, dp_ratio, pixels_per_inch);
+
+		else if (name == TRANSITION)
+			values.transition = p->Get<TransitionList>();
+		else if (name == ANIMATION)
+			values.animation = p->Get<AnimationList>();
+
 	}
 
 

+ 1 - 1
Source/Core/ElementUtilities.cpp

@@ -149,7 +149,7 @@ int ElementUtilities::GetLineHeight(Element* element)
 {
 	const Property* line_height_property = element->GetLineHeightProperty();
 
-	if (line_height_property->unit & Property::LENGTH && line_height_property->unit != Property::NUMBER)
+	if (line_height_property->unit & Property::LENGTH)
 	{
 		float value = element->GetStyle()->ResolveLength(line_height_property);
 		return Math::RoundToInteger(value);

+ 4 - 4
Source/Core/LayoutBlockBox.cpp

@@ -90,7 +90,7 @@ LayoutBlockBox::LayoutBlockBox(LayoutEngine* _layout_engine, LayoutBlockBox* _pa
 			if (self_offset_parent != this)
 			{
 				// Get the next position within our offset parent's containing block.
-				parent->PositionBlockBox(position, box, element->GetProperty< int >(CLEAR));
+				parent->PositionBlockBox(position, box, element->GetComputedValues().clear);
 				element->SetOffset(position - (self_offset_parent->GetPosition() - offset_root->GetPosition()), self_offset_parent->GetElement());
 			}
 			else
@@ -144,7 +144,7 @@ LayoutBlockBox::LayoutBlockBox(LayoutEngine* _layout_engine, LayoutBlockBox* _pa
 	vertical_overflow = false;
 
 	layout_engine->BuildBox(box, min_height, max_height, parent, NULL);
-	parent->PositionBlockBox(position, box, 0);
+	parent->PositionBlockBox(position, box, Style::Clear::None);
 	box.SetContent(Vector2f(box.GetSize(Box::CONTENT).x, -1));
 
 	// Reset the min and max heights; they're not valid for inline block boxes.
@@ -482,7 +482,7 @@ void LayoutBlockBox::CloseAbsoluteElements()
 }
 
 // Returns the offset from the top-left corner of this box that the next child box will be positioned at.
-void LayoutBlockBox::PositionBox(Vector2f& box_position, float top_margin, int clear_property) const
+void LayoutBlockBox::PositionBox(Vector2f& box_position, float top_margin, Style::Clear clear_property) const
 {
 	// If our element is establishing a new offset hierarchy, then any children of ours don't inherit our offset.
 	box_position = GetPosition();
@@ -506,7 +506,7 @@ void LayoutBlockBox::PositionBox(Vector2f& box_position, float top_margin, int c
 
 // Returns the offset from the top-left corner of this box's offset element the next child block box, of the given
 // dimensions, will be positioned at. This will include the margins on the new block box.
-void LayoutBlockBox::PositionBlockBox(Vector2f& box_position, const Box& box, int clear_property) const
+void LayoutBlockBox::PositionBlockBox(Vector2f& box_position, const Box& box, Style::Clear clear_property) const
 {
 	PositionBox(box_position, box.GetEdge(Box::MARGIN, Box::TOP), clear_property);
 	box_position.x += box.GetEdge(Box::MARGIN, Box::LEFT);

+ 2 - 2
Source/Core/LayoutBlockBox.h

@@ -115,13 +115,13 @@ public:
 	/// @param[out] box_position The box cursor position.
 	/// @param[in] top_margin The top margin of the box. This will be collapsed as appropriate against other block boxes.
 	/// @param[in] clear_property The value of the underlying element's clear property.
-	void PositionBox(Vector2f& box_position, float top_margin = 0, int clear_property = 0) const;
+	void PositionBox(Vector2f& box_position, float top_margin = 0, Style::Clear clear_property = Style::Clear::None) const;
 	/// Returns the offset from the top-left corner of this box's offset element the next child block box, of the
 	/// given dimensions, will be positioned at. This will include the margins on the new block box.
 	/// @param[out] box_position The block box cursor position.
 	/// @param[in] box The dimensions of the new box.
 	/// @param[in] clear_property The value of the underlying element's clear property.
-	void PositionBlockBox(Vector2f& box_position, const Box& box, int clear_property) const;
+	void PositionBlockBox(Vector2f& box_position, const Box& box, Style::Clear clear_property) const;
 	/// Returns the offset from the top-left corner of this box for the next line.
 	/// @param box_position[out] The line box position.
 	/// @param box_width[out] The available width for the line box.

+ 7 - 6
Source/Core/LayoutBlockBoxSpace.cpp

@@ -76,7 +76,7 @@ float LayoutBlockBoxSpace::PositionBox(float cursor, Element* element)
 	}
 
 	// Shift the cursor down past to clear boxes, if necessary.
-	cursor = ClearBoxes(cursor, element->GetProperty< int >(CLEAR));
+	cursor = ClearBoxes(cursor, element->GetComputedValues().clear);
 
 	// Find a place to put this box.
 	Vector2f element_offset;
@@ -101,19 +101,20 @@ float LayoutBlockBoxSpace::PositionBox(float cursor, Element* element)
 
 // Determines the appropriate vertical position for an object that is choosing to clear floating elements to the left
 // or right (or both).
-float LayoutBlockBoxSpace::ClearBoxes(float cursor, int clear_property)
+float LayoutBlockBoxSpace::ClearBoxes(float cursor, Style::Clear clear_property)
 {
+	using namespace Style;
 	// Clear left boxes.
-	if (clear_property == CLEAR_LEFT ||
-		clear_property == CLEAR_BOTH)
+	if (clear_property == Clear::Left ||
+		clear_property == Clear::Both)
 	{
 		for (size_t i = 0; i < boxes[LEFT].size(); ++i)
 			cursor = Math::Max(cursor, boxes[LEFT][i].offset.y + boxes[LEFT][i].dimensions.y);
 	}
 
 	// Clear right boxes.
-	if (clear_property == CLEAR_RIGHT ||
-		clear_property == CLEAR_BOTH)
+	if (clear_property == Clear::Right ||
+		clear_property == Clear::Both)
 	{
 		for (size_t i = 0; i < boxes[RIGHT].size(); ++i)
 			cursor = Math::Max(cursor, boxes[RIGHT][i].offset.y + boxes[RIGHT][i].dimensions.y);

+ 1 - 1
Source/Core/LayoutBlockBoxSpace.h

@@ -72,7 +72,7 @@ public:
 	/// @param[in] cursor The ideal vertical position.
 	/// @param[in] clear_property The value of the clear property of the clearing object.
 	/// @return The appropriate vertical position for the clearing object.
-	float ClearBoxes(float cursor, int clear_property);
+	float ClearBoxes(float cursor, Style::Clear clear_property);
 
 	/// Returns the top-left corner of the boxes within the space.
 	/// @return The space's offset.