Browse Source

Make font face handle a computed value, making it cheap to inherit from parent element.

Michael Ragazzon 6 years ago
parent
commit
642d096e44

+ 5 - 0
Include/RmlUi/Core/ComputedValues.h

@@ -34,6 +34,8 @@
 namespace Rml {
 namespace Core {
 
+class FontFaceHandle;
+
 namespace Style
 {
 
@@ -173,6 +175,9 @@ struct ComputedValues
 	FontStyle font_style = FontStyle::Normal;
 	FontWeight font_weight = FontWeight::Normal;
 	float font_size = 12.f;
+	// Font face used to render text and resolve ex properties. Does not represent a true property
+	// like most computed values, but placed here as it is used and inherited in a similar manner.
+	SharedPtr<FontFaceHandle> font_face_handle;
 
 	TextAlign text_align = TextAlign::Left;
 	TextDecoration text_decoration = TextDecoration::None;

+ 0 - 6
Include/RmlUi/Core/Element.h

@@ -605,9 +605,6 @@ protected:
 	/// Returns true if the element has been marked as needing a re-layout.
 	virtual bool IsLayoutDirty();
 
-	/// Forces a reevaluation of applicable font effects.
-	virtual void DirtyFont();
-
 	/// Returns the RML of this element and all children.
 	/// @param[out] content The content of this element and those under it, in XML form.
 	virtual void GetRML(String& content);
@@ -727,9 +724,6 @@ private:
 	bool computed_values_are_default_initialized;
 	bool box_dirty;
 
-	// The element's font face; used to render text and resolve em / ex properties.
-	SharedPtr<FontFaceHandle> font_face_handle;
-	
 	// Cached rendering information
 	int clipping_ignore_depth;
 	bool clipping_enabled;

+ 1 - 31
Source/Core/Element.cpp

@@ -153,8 +153,6 @@ transform_state(), transform_state_perspective_dirty(true), transform_state_tran
 	computed_values_are_default_initialized = true;
 	box_dirty = false;
 
-	font_face_handle = nullptr;
-	
 	clipping_ignore_depth = 0;
 	clipping_enabled = false;
 	clipping_state_dirty = true;
@@ -192,8 +190,6 @@ Element::~Element()
 	num_non_dom_children = 0;
 
 	delete element_meta;
-
-	font_face_handle.reset();
 }
 
 void Element::Update(float dp_ratio)
@@ -593,7 +589,7 @@ float Element::GetZIndex() const
 // Returns the element's font face handle.
 FontFaceHandle* Element::GetFontFaceHandle() const
 {
-	return font_face_handle.get();
+	return element_meta->computed_values.font_face_handle.get();
 }
 
 // Sets a local property override on the element.
@@ -1788,25 +1784,6 @@ void Element::OnPropertyChange(const PropertyIdSet& changed_properties)
 		}
 	}
 
-	// Fetch a new font face if it has been changed.
-	if (changed_properties.Contains(PropertyId::FontFamily) ||
-		changed_properties.Contains(PropertyId::FontCharset) ||
-		changed_properties.Contains(PropertyId::FontWeight) ||
-		changed_properties.Contains(PropertyId::FontStyle) ||
-		changed_properties.Contains(PropertyId::FontSize))
-	{
-		// Fetch the new font face.
-		SharedPtr<FontFaceHandle> new_font_face_handle = ElementUtilities::GetFontFaceHandle(element_meta->computed_values);
-
-		// If this is different from our current font face, then we've got to nuke
-		// all our characters and tell our parent that we have to be re-laid out.
-		if (new_font_face_handle != font_face_handle)
-		{
-			font_face_handle = new_font_face_handle;
-		}
-	}
-
-
 	// Update the position.
 	if (changed_properties.Contains(PropertyId::Left) ||
 		changed_properties.Contains(PropertyId::Right) ||
@@ -1953,13 +1930,6 @@ bool Element::IsLayoutDirty()
 	return false;
 }
 
-// Forces a reevaluation of applicable font effects.
-void Element::DirtyFont()
-{
-	for (size_t i = 0; i < children.size(); ++i)
-		children[i]->DirtyFont();
-}
-
 void Element::ProcessDefaultAction(Event& event)
 {
 	if (event == EventId::Mousedown && IsPointWithinElement(Vector2f(event.GetParameter< float >("mouse_x", 0), event.GetParameter< float >("mouse_y", 0))) &&

+ 9 - 0
Source/Core/ElementStyle.cpp

@@ -602,6 +602,7 @@ PropertyIdSet ElementStyle::ComputeValues(Style::ComputedValues& values, const S
 		values.font_charset = parent_values->font_charset;
 		values.font_style = parent_values->font_style;
 		values.font_weight = parent_values->font_weight;
+		values.font_face_handle = parent_values->font_face_handle;
 
 		values.text_align = parent_values->text_align;
 		values.text_decoration = parent_values->text_decoration;
@@ -765,18 +766,23 @@ PropertyIdSet ElementStyle::ComputeValues(Style::ComputedValues& values, const S
 
 		case PropertyId::FontFamily:
 			values.font_family = StringUtilities::ToLower(p->Get<String>());
+			values.font_face_handle.reset();
 			break;
 		case PropertyId::FontCharset:
 			values.font_charset = p->Get<String>();
+			values.font_face_handle.reset();
 			break;
 		case PropertyId::FontStyle:
 			values.font_style = (FontStyle)p->Get< int >();
+			values.font_face_handle.reset();
 			break;
 		case PropertyId::FontWeight:
 			values.font_weight = (FontWeight)p->Get< int >();
+			values.font_face_handle.reset();
 			break;
 		case PropertyId::FontSize:
 			// (font-size computed above)
+			values.font_face_handle.reset();
 			break;
 
 		case PropertyId::TextAlign:
@@ -886,6 +892,9 @@ PropertyIdSet ElementStyle::ComputeValues(Style::ComputedValues& values, const S
 		}
 	}
 
+	// The font-face handle is nulled when local font properties are set. In that case we need to retrieve a new handle.
+	if (!values.font_face_handle)
+		values.font_face_handle = ElementUtilities::GetFontFaceHandle(values);
 
 	// Next, pass inheritable dirty properties onto our children
 	PropertyIdSet dirty_inherited_properties = (dirty_properties & StyleSheetSpecification::GetRegisteredInheritedProperties());

+ 0 - 6
Source/Core/ElementTextDefault.cpp

@@ -362,12 +362,6 @@ void ElementTextDefault::GetRML(String& content)
 	content += StringUtilities::ToUTF8(text);
 }
 
-// Forces a reevaluation of applicable font effects.
-void ElementTextDefault::DirtyFont()
-{
-	font_dirty = true;
-}
-
 // Updates the configuration this element uses for its font.
 bool ElementTextDefault::UpdateFontConfiguration()
 {

+ 0 - 3
Source/Core/ElementTextDefault.h

@@ -84,9 +84,6 @@ protected:
 	/// @param content[out] The raw text.
 	void GetRML(String& content) override;
 
-	/// Forces a reevaluation of applicable font effects.
-	void DirtyFont() override;
-
 private:
 	// Updates the configuration this element uses for its font, depending on which font effects
 	// are active.