Browse Source

Make the resolve length functions safer, returns zero if unsuccessful. Rename to ResolveLength (emphasizes returned unit). Add Element::ResolveLength(property_name). See #55.

Michael Ragazzon 6 years ago
parent
commit
039841c537

+ 8 - 4
Include/RmlUi/Core/Element.h

@@ -223,11 +223,15 @@ public:
 	/// @return The local properties for this element, or nullptr if no properties defined
 	/// @return The local properties for this element, or nullptr if no properties defined
 	const PropertyMap& GetLocalStyleProperties();
 	const PropertyMap& GetLocalStyleProperties();
 
 
-	/// Resolves a property with units of length or percentage to 'px'. Percentages are resolved by scaling the base value.
+	/// Resolves a property with units of number, length, or percentage to a length in 'px' units.
 	/// @param[in] name The property to resolve the value for.
 	/// @param[in] name The property to resolve the value for.
-	/// @param[in] base_value The value that is scaled by the percentage value, if it is a percentage.
-	/// @return The resolved value in 'px' unit.
-	float ResolveLengthPercentage(const Property *property, float base_value);
+	/// @param[in] base_value The value that is scaled by the number or percentage value, if applicable.
+	/// @return The resolved value in 'px' unit, or zero if it could not be resolved.
+	float ResolveLength(const Property *property, float base_value);
+	/// Resolve a property by its name to length in 'px' units. The specified property should be a number, length or percentage.
+	/// @param[in] name The property to resolve the value for.
+	/// @return The resolved value in 'px' unit, or zero if it could not be resolved.
+	float ResolveLength(const String& property_name);
 
 
 	/// Returns the size of the containing block. Often percentages are scaled relative to this.
 	/// Returns the size of the containing block. Often percentages are scaled relative to this.
 	Vector2f GetContainingBlock();
 	Vector2f GetContainingBlock();

+ 0 - 13
Source/Core/ComputeProperty.cpp

@@ -110,9 +110,6 @@ float ComputeLength(const Property* property, float font_size, float document_fo
 	return 0.0f;
 	return 0.0f;
 }
 }
 
 
-
-
-
 float ComputeAbsoluteLength(const Property& property, float dp_ratio)
 float ComputeAbsoluteLength(const Property& property, float dp_ratio)
 {
 {
 	RMLUI_ASSERT(property.unit & Property::ABSOLUTE_LENGTH);
 	RMLUI_ASSERT(property.unit & Property::ABSOLUTE_LENGTH);
@@ -151,9 +148,6 @@ float ComputeAbsoluteLength(const Property& property, float dp_ratio)
 	return 0.0f;
 	return 0.0f;
 }
 }
 
 
-
-
-// Resolves one of this element's properties.
 float ComputeFontsize(const Property& property, const Style::ComputedValues& values, const Style::ComputedValues* parent_values, const Style::ComputedValues* document_values, float dp_ratio)
 float ComputeFontsize(const Property& property, const Style::ComputedValues& values, const Style::ComputedValues* parent_values, const Style::ComputedValues* document_values, float dp_ratio)
 {
 {
 	// The calculated value of the font-size property is inherited, so we need to check if this
 	// The calculated value of the font-size property is inherited, so we need to check if this
@@ -188,7 +182,6 @@ float ComputeFontsize(const Property& property, const Style::ComputedValues& val
 	return ComputeAbsoluteLength(property, dp_ratio);
 	return ComputeAbsoluteLength(property, dp_ratio);
 }
 }
 
 
-
 Style::Clip ComputeClip(const Property* property)
 Style::Clip ComputeClip(const Property* property)
 {
 {
 	int value = property->Get<int>();
 	int value = property->Get<int>();
@@ -226,7 +219,6 @@ Style::LineHeight ComputeLineHeight(const Property* property, float font_size, f
 	return Style::LineHeight(value, Style::LineHeight::Number, scale_factor);
 	return Style::LineHeight(value, Style::LineHeight::Number, scale_factor);
 }
 }
 
 
-
 Style::VerticalAlign ComputeVerticalAlign(const Property* property, float line_height, float font_size, float document_font_size, float dp_ratio)
 Style::VerticalAlign ComputeVerticalAlign(const Property* property, float line_height, float font_size, float document_font_size, float dp_ratio)
 {
 {
 	if (property->unit & Property::LENGTH)
 	if (property->unit & Property::LENGTH)
@@ -289,10 +281,5 @@ Style::LengthPercentage ComputeOrigin(const Property* property, float font_size,
 }
 }
 
 
 
 
-
-
-
-
-
 }
 }
 }
 }

+ 4 - 4
Source/Core/DecoratorNinePatch.cpp

@@ -102,10 +102,10 @@ DecoratorDataHandle DecoratorNinePatch::GenerateElementData(Element* element) co
 	{
 	{
 		const float dp_ratio = ElementUtilities::GetDensityIndependentPixelRatio(element);
 		const float dp_ratio = ElementUtilities::GetDensityIndependentPixelRatio(element);
 		float lengths[4]; // top, right, bottom, left
 		float lengths[4]; // top, right, bottom, left
-		lengths[0] = element->ResolveLengthPercentage(&(*edges)[0], dp_ratio * (surface_pos[1].y - surface_pos[0].y));
-		lengths[1] = element->ResolveLengthPercentage(&(*edges)[1], dp_ratio * (surface_pos[3].x - surface_pos[2].x));
-		lengths[2] = element->ResolveLengthPercentage(&(*edges)[2], dp_ratio * (surface_pos[3].y - surface_pos[2].y));
-		lengths[3] = element->ResolveLengthPercentage(&(*edges)[3], dp_ratio * (surface_pos[1].x - surface_pos[0].x));
+		lengths[0] = element->ResolveLength(&(*edges)[0], dp_ratio * (surface_pos[1].y - surface_pos[0].y));
+		lengths[1] = element->ResolveLength(&(*edges)[1], dp_ratio * (surface_pos[3].x - surface_pos[2].x));
+		lengths[2] = element->ResolveLength(&(*edges)[2], dp_ratio * (surface_pos[3].y - surface_pos[2].y));
+		lengths[3] = element->ResolveLength(&(*edges)[3], dp_ratio * (surface_pos[1].x - surface_pos[0].x));
 
 
 		surface_pos[1].y = lengths[0];
 		surface_pos[1].y = lengths[0];
 		surface_pos[2].x = surface_dimensions.x - lengths[1];
 		surface_pos[2].x = surface_dimensions.x - lengths[1];

+ 17 - 3
Source/Core/Element.cpp

@@ -642,10 +642,24 @@ const PropertyMap& Element::GetLocalStyleProperties()
 	return style->GetLocalStyleProperties();
 	return style->GetLocalStyleProperties();
 }
 }
 
 
-// Resolves one of this element's style.
-float Element::ResolveLengthPercentage(const Property *property, float base_value)
+float Element::ResolveLength(const Property *property, float base_value)
 {
 {
-	return style->ResolveLengthPercentage(property, base_value);
+	return style->ResolveLength(property, base_value);
+}
+
+float Element::ResolveLength(const String& property_name)
+{
+	auto property = style->GetProperty(StyleSheetSpecification::GetPropertyId(property_name));
+	if (!property)
+		return 0.0f;
+
+	RelativeTarget relative_target = RelativeTarget::None;
+	if (property->definition)
+		relative_target = property->definition->GetRelativeTarget();
+
+	float result = style->ResolveLength(property, relative_target);
+	
+	return result;
 }
 }
 
 
 Vector2f Element::GetContainingBlock()
 Vector2f Element::GetContainingBlock()

+ 2 - 2
Source/Core/ElementAnimation.cpp

@@ -97,8 +97,8 @@ static Property InterpolateProperties(const Property & p0, const Property& p1, f
 		else
 		else
 		{
 		{
 			// Otherwise, convert units to pixels.
 			// Otherwise, convert units to pixels.
-			float f0 = element.GetStyle()->ResolveNumberLengthPercentage(&p0, definition->GetRelativeTarget());
-			float f1 = element.GetStyle()->ResolveNumberLengthPercentage(&p1, definition->GetRelativeTarget());
+			float f0 = element.GetStyle()->ResolveLength(&p0, definition->GetRelativeTarget());
+			float f1 = element.GetStyle()->ResolveLength(&p1, definition->GetRelativeTarget());
 			float f = (1.0f - alpha) * f0 + alpha * f1;
 			float f = (1.0f - alpha) * f0 + alpha * f1;
 			return Property{ f, Property::PX };
 			return Property{ f, Property::PX };
 		}
 		}

+ 34 - 25
Source/Core/ElementStyle.cpp

@@ -342,12 +342,39 @@ const PropertyMap& ElementStyle::GetLocalStyleProperties() const
 	return inline_properties.GetProperties();
 	return inline_properties.GetProperties();
 }
 }
 
 
-float ElementStyle::ResolveNumberLengthPercentage(const Property * property, RelativeTarget relative_target) const
+float ElementStyle::ResolveLength(const Property* property, float base_value) const
 {
 {
+	if (!property || !(property->unit & Property::NUMBER_LENGTH_PERCENT))
+		return 0.0f;
+
+	if (property->unit & Property::NUMBER)
+		return property->Get<float>() * base_value;
+	else if (property->unit & Property::PERCENT)
+		return property->Get<float>() * base_value * 0.01f;
+
+	const float dp_ratio = ElementUtilities::GetDensityIndependentPixelRatio(element);
+	const float font_size = element->GetComputedValues().font_size;
+
+	auto doc = element->GetOwnerDocument();
+	const float doc_font_size = (doc ? doc->GetComputedValues().font_size : DefaultComputedValues.font_size);
+
+	float result = ComputeLength(property, font_size, doc_font_size, dp_ratio);
+
+	return result;
+}
+
+float ElementStyle::ResolveLength(const Property* property, RelativeTarget relative_target) const
+{
+	RMLUI_ASSERT(property);
+
 	// There is an exception on font-size properties, as 'em' units here refer to parent font size instead
 	// There is an exception on font-size properties, as 'em' units here refer to parent font size instead
 	if ((property->unit & Property::LENGTH) && !(property->unit == Property::EM && relative_target == RelativeTarget::ParentFontSize))
 	if ((property->unit & Property::LENGTH) && !(property->unit == Property::EM && relative_target == RelativeTarget::ParentFontSize))
 	{
 	{
-		float result = ComputeLength(property, element->GetComputedValues().font_size, element->GetOwnerDocument()->GetComputedValues().font_size, ElementUtilities::GetDensityIndependentPixelRatio(element));
+		auto doc = element->GetOwnerDocument();
+		const float doc_font_size = (doc ? doc->GetComputedValues().font_size : DefaultComputedValues.font_size);
+
+		float result = ComputeLength(property, element->GetComputedValues().font_size, doc_font_size, ElementUtilities::GetDensityIndependentPixelRatio(element));
+
 		return result;
 		return result;
 	}
 	}
 
 
@@ -356,7 +383,7 @@ float ElementStyle::ResolveNumberLengthPercentage(const Property * property, Rel
 	switch (relative_target)
 	switch (relative_target)
 	{
 	{
 	case RelativeTarget::None:
 	case RelativeTarget::None:
-		base_value = 1.0f;
+		base_value = 0.0f;
 		break;
 		break;
 	case RelativeTarget::ContainingBlockWidth:
 	case RelativeTarget::ContainingBlockWidth:
 		base_value = element->GetContainingBlock().x;
 		base_value = element->GetContainingBlock().x;
@@ -368,7 +395,10 @@ float ElementStyle::ResolveNumberLengthPercentage(const Property * property, Rel
 		base_value = element->GetComputedValues().font_size;
 		base_value = element->GetComputedValues().font_size;
 		break;
 		break;
 	case RelativeTarget::ParentFontSize:
 	case RelativeTarget::ParentFontSize:
-		base_value = element->GetParentNode()->GetComputedValues().font_size;
+	{
+		auto p = element->GetParentNode();
+		base_value = (p ? p->GetComputedValues().font_size : DefaultComputedValues.font_size);
+	}
 		break;
 		break;
 	case RelativeTarget::LineHeight:
 	case RelativeTarget::LineHeight:
 		base_value = element->GetLineHeight();
 		base_value = element->GetLineHeight();
@@ -395,27 +425,6 @@ float ElementStyle::ResolveNumberLengthPercentage(const Property * property, Rel
 	return base_value * scale_value;
 	return base_value * scale_value;
 }
 }
 
 
-// Resolves one of this element's properties.
-float ElementStyle::ResolveLengthPercentage(const Property* property, float base_value) const
-{
-	if (!property)
-	{
-		RMLUI_ERROR;
-		return 0.0f;
-	}
-	RMLUI_ASSERT(property->unit & Property::LENGTH_PERCENT);
-
-	const float font_size = element->GetComputedValues().font_size;
-	const float doc_font_size = element->GetOwnerDocument()->GetComputedValues().font_size;
-	const float dp_ratio = ElementUtilities::GetDensityIndependentPixelRatio(element);
-
-	Style::LengthPercentage computed = ComputeLengthPercentage(property, font_size, doc_font_size, dp_ratio);
-
-	float result = ResolveValue(computed, base_value);
-
-	return result;
-}
-
 void ElementStyle::DirtyDefinition()
 void ElementStyle::DirtyDefinition()
 {
 {
 	definition_dirty = true;
 	definition_dirty = true;

+ 8 - 8
Source/Core/ElementStyle.h

@@ -103,14 +103,14 @@ public:
 	/// Returns the local style properties, excluding any properties from local class.
 	/// Returns the local style properties, excluding any properties from local class.
 	const PropertyMap& GetLocalStyleProperties() const;
 	const PropertyMap& GetLocalStyleProperties() const;
 
 
-	/// Resolves a property with units of length or percentage to 'px'. Percentages are resolved by scaling the base value.
-	/// @param[in] name The property to resolve the value for.
-	/// @param[in] base_value The value that is scaled by the percentage value, if it is a percentage.
-	/// @return The resolved value in 'px' unit.
-	float ResolveLengthPercentage(const Property *property, float base_value) const;
-	/// Resolves a property with units of number, length or percentage. Lengths are resolved to 'px'. 
-	/// Number and percentages are resolved by scaling the size of the specified target.
-	float ResolveNumberLengthPercentage(const Property* property, RelativeTarget relative_target) const;
+	/// Resolves a property with units of number, length, or percentage to a length in 'px' units.
+	/// @param[in] property The property to resolve the value for.
+	/// @param[in] base_value The value that is scaled by the number or percentage value, if applicable.
+	/// @return The resolved value in 'px' unit, or zero if it could not be resolved.
+	float ResolveLength(const Property* property, float base_value) const;
+	/// Resolves a property with units of number, length, or percentage to a length in 'px' units.
+	/// Numbers and percentages are resolved by scaling the size of the specified target.
+	float ResolveLength(const Property* property, RelativeTarget relative_target) const;
 
 
 	/// Mark definition and all children dirty.
 	/// Mark definition and all children dirty.
 	void DirtyDefinition();
 	void DirtyDefinition();

+ 1 - 1
Source/Core/PropertyDefinition.cpp

@@ -150,7 +150,7 @@ bool PropertyDefinition::GetValue(String& value, const Property& property) const
 		case Property::COLOUR:
 		case Property::COLOUR:
 		{
 		{
 			Colourb colour = property.value.Get< Colourb >();
 			Colourb colour = property.value.Get< Colourb >();
-			value = CreateString(32, "rgb(%d,%d,%d,%d)", colour.red, colour.green, colour.blue, colour.alpha);
+			value = CreateString(32, "rgba(%d,%d,%d,%d)", colour.red, colour.green, colour.blue, colour.alpha);
 		}
 		}
 		break;
 		break;
 
 

+ 1 - 1
Source/Core/TransformPrimitive.cpp

@@ -91,7 +91,7 @@ float NumericValue::ResolveLengthPercentage(Element& e, float base) const noexce
 	Property prop;
 	Property prop;
 	prop.value = Variant(number);
 	prop.value = Variant(number);
 	prop.unit = unit;
 	prop.unit = unit;
-	return e.ResolveLengthPercentage(&prop, base);
+	return e.ResolveLength(&prop, base);
 }
 }
 
 
 float NumericValue::ResolveWidth(Element& e) const noexcept
 float NumericValue::ResolveWidth(Element& e) const noexcept