Forráskód Böngészése

Performence improvements. Layout updates are only done once per frame, transform updates are faster in most cases.

Michael 7 éve
szülő
commit
c84b9fd505

+ 4 - 2
Include/Rocket/Core/ElementDocument.h

@@ -127,13 +127,15 @@ public:
 	virtual void LoadScript(Stream* stream, const String& source_name);
 
 	/// Updates the layout if necessary.
-	inline void UpdateLayout() { if (layout_dirty && lock_layout == 0) _UpdateLayout(); }
+	/// The extra argument was added such that layout updates can be done only once per frame
+	inline void UpdateLayout(bool i_really_mean_it = false) { if (i_really_mean_it && layout_dirty && lock_layout == 0) _UpdateLayout(); }
+
 	/// Updates the position of the document based on the style properties.
 	void UpdatePosition();
 	
 	/// Increment/Decrement the layout lock
 	void LockLayout(bool lock);
-
+	
 protected:
 	/// Refreshes the document layout if required.
 	virtual void OnUpdate();

+ 2 - 2
Samples/basic/transform/data/transform.rml

@@ -31,12 +31,12 @@
 
 		scrollbarvertical sliderbar:hover,scrollbarvertical sliderbar:active
 		{
-			transform: translateZ(10);
+			transform: translateZ(10px);
 		}
 
 		p
 		{
-			transform: translateZ(10);
+			transform: translateZ(10px);
 		}
 	</style>
 </head>

+ 1 - 1
Samples/basic/transform/src/main.cpp

@@ -63,7 +63,7 @@ public:
 		if (document)
 		{
 			std::stringstream s;
-			s << distance;
+			s << distance << "px";
 			document->SetProperty("perspective", s.str().c_str());
 		}
 	}

+ 1 - 2
Samples/shell/src/win32/InputWin32.cpp

@@ -93,8 +93,7 @@ void InputWin32::ProcessWindowsEvent(UINT message, WPARAM w_param, LPARAM l_para
 			int key_modifier_state = GetKeyModifierState();
 
 			// Check for a shift-~ to toggle the debugger.
-			if (key_identifier == Rocket::Core::Input::KI_OEM_3 &&
-				key_modifier_state & Rocket::Core::Input::KM_SHIFT)
+			if (key_identifier == Rocket::Core::Input::KI_F8)
 			{
 				Rocket::Debugger::SetVisible(!Rocket::Debugger::IsVisible());
 				break;

+ 1 - 1
Samples/shell/src/win32/ShellWin32.cpp

@@ -193,7 +193,7 @@ void Shell::EventLoop(ShellIdleFunction idle_function)
 		idle_function();
 
 		if (!activated)
-			Sleep(100);
+			Sleep(10);
 	}
 }
 

+ 8 - 7
Source/Core/Context.cpp

@@ -202,7 +202,8 @@ bool Context::Render()
 	// Update the layout for all documents in the root. This is done now as events during the
 	// update may have caused elements to require an update.
 	for (int i = 0; i < root->GetNumChildren(); ++i)
-		root->GetChild(i)->UpdateLayout();
+		if (auto doc = root->GetChild(i)->GetOwnerDocument())
+			doc->UpdateLayout(true);
 
 	render_interface->context = this;
 	ElementUtilities::ApplyActiveClipRegion(this, render_interface);
@@ -215,9 +216,9 @@ bool Context::Render()
 	if (cursor_proxy != NULL)
 	{
 		cursor_proxy->Update();
-		cursor_proxy->SetOffset(Vector2f((float) Math::Clamp(mouse_position.x, 0, dimensions.x),
-													 (float) Math::Clamp(mouse_position.y, 0, dimensions.y)),
-								NULL);
+		cursor_proxy->SetOffset(Vector2f((float)Math::Clamp(mouse_position.x, 0, dimensions.x),
+			(float)Math::Clamp(mouse_position.y, 0, dimensions.y)),
+			NULL);
 		cursor_proxy->Render();
 	}
 
@@ -226,9 +227,9 @@ bool Context::Render()
 		show_cursor)
 	{
 		active_cursor->Update();
-		active_cursor->SetOffset(Vector2f((float) Math::Clamp(mouse_position.x, 0, dimensions.x),
-													 (float) Math::Clamp(mouse_position.y, 0, dimensions.y)),
-								 NULL);
+		active_cursor->SetOffset(Vector2f((float)Math::Clamp(mouse_position.x, 0, dimensions.x),
+			(float)Math::Clamp(mouse_position.y, 0, dimensions.y)),
+			NULL);
 		active_cursor->Render();
 	}
 

+ 144 - 137
Source/Core/Element.cpp

@@ -2366,44 +2366,49 @@ void Element::DirtyTransformState(bool perspective_changed, bool transform_chang
 
 void Element::UpdateTransformState()
 {
-	Context *context = GetContext();
-
-	Vector2f pos = GetAbsoluteOffset(Box::BORDER);
-	Vector2f size = GetBox().GetSize(Box::BORDER);
+	if (!(transform_state_perspective_dirty || transform_state_transform_dirty || transform_state_parent_transform_dirty))
+	{
+		return;
+	}
 
-	if (transform_state_perspective_dirty || transform_state_transform_dirty || transform_state_parent_transform_dirty)
+	if (!transform_state.get())
 	{
-		if (!transform_state.get())
-		{
-			transform_state.reset(new TransformState());
-		}
+		transform_state.reset(new TransformState());
 	}
 
-	if (transform_state_perspective_dirty)
+
+	if(transform_state_perspective_dirty || transform_state_transform_dirty)
 	{
-		bool have_perspective = false;
-		TransformState::Perspective perspective_value;
+		Context *context = GetContext();
+		Vector2f pos = GetAbsoluteOffset(Box::BORDER);
+		Vector2f size = GetBox().GetSize(Box::BORDER);
 
-		perspective_value.vanish = Vector2f(pos.x + size.x * 0.5f, pos.y + size.y * 0.5f);
 
-		const Property *perspective = GetPerspective();
-		if (perspective && (perspective->unit != Property::KEYWORD || perspective->value.Get< int >() != PERSPECTIVE_NONE))
+		if (transform_state_perspective_dirty)
 		{
-			have_perspective = true;
+			bool have_perspective = false;
+			TransformState::Perspective perspective_value;
 
-			// Compute the perspective value
-			perspective_value.distance = ResolveProperty(perspective, Math::Max(size.x, size.y));
+			perspective_value.vanish = Vector2f(pos.x + size.x * 0.5f, pos.y + size.y * 0.5f);
 
-			// Compute the perspective origin, if necessary
-			if (perspective_value.distance > 0)
+			const Property *perspective = GetPerspective();
+			if (perspective && (perspective->unit != Property::KEYWORD || perspective->value.Get< int >() != PERSPECTIVE_NONE))
 			{
-				const Property *perspective_origin_x = GetPerspectiveOriginX();
-				if (perspective_origin_x)
+				have_perspective = true;
+
+				// Compute the perspective value
+				perspective_value.distance = ResolveProperty(perspective, Math::Max(size.x, size.y));
+
+				// Compute the perspective origin, if necessary
+				if (perspective_value.distance > 0)
 				{
-					if (perspective_origin_x->unit == Property::KEYWORD)
+					const Property *perspective_origin_x = GetPerspectiveOriginX();
+					if (perspective_origin_x)
 					{
-						switch (perspective_origin_x->value.Get< int >())
+						if (perspective_origin_x->unit == Property::KEYWORD)
 						{
+							switch (perspective_origin_x->value.Get< int >())
+							{
 							case PERSPECTIVE_ORIGIN_X_LEFT:
 								perspective_value.vanish.x = pos.x;
 								break;
@@ -2415,21 +2420,21 @@ void Element::UpdateTransformState()
 							case PERSPECTIVE_ORIGIN_X_RIGHT:
 								perspective_value.vanish.x = pos.x + size.x;
 								break;
+							}
+						}
+						else
+						{
+							perspective_value.vanish.x = pos.x + ResolveProperty(perspective_origin_x, size.x);
 						}
 					}
-					else
-					{
-						perspective_value.vanish.x = pos.x + ResolveProperty(perspective_origin_x, size.x);
-					}
-				}
 
-				const Property *perspective_origin_y = GetPerspectiveOriginY();
-				if (perspective_origin_y)
-				{
-					if (perspective_origin_y->unit == Property::KEYWORD)
+					const Property *perspective_origin_y = GetPerspectiveOriginY();
+					if (perspective_origin_y)
 					{
-						switch (perspective_origin_y->value.Get< int >())
+						if (perspective_origin_y->unit == Property::KEYWORD)
 						{
+							switch (perspective_origin_y->value.Get< int >())
+							{
 							case PERSPECTIVE_ORIGIN_Y_TOP:
 								perspective_value.vanish.y = pos.y;
 								break;
@@ -2441,68 +2446,68 @@ void Element::UpdateTransformState()
 							case PERSPECTIVE_ORIGIN_Y_BOTTOM:
 								perspective_value.vanish.y = pos.y + size.y;
 								break;
+							}
+						}
+						else
+						{
+							perspective_value.vanish.y = pos.y + ResolveProperty(perspective_origin_y, size.y);
 						}
-					}
-					else
-					{
-						perspective_value.vanish.y = pos.y + ResolveProperty(perspective_origin_y, size.y);
 					}
 				}
 			}
-		}
 
-		if (have_perspective && context)
-		{
-			perspective_value.view_size = context->GetDimensions();
-			transform_state->SetPerspective(&perspective_value);
-		}
-		else
-		{
-			transform_state->SetPerspective(0);
-		}
+			if (have_perspective && context)
+			{
+				perspective_value.view_size = context->GetDimensions();
+				transform_state->SetPerspective(&perspective_value);
+			}
+			else
+			{
+				transform_state->SetPerspective(0);
+			}
 
-		transform_state_perspective_dirty = false;
-	}
+			transform_state_perspective_dirty = false;
+		}
 
-	if (transform_state_transform_dirty)
-	{
-		bool have_local_perspective = false;
-		TransformState::LocalPerspective local_perspective;
+		if (transform_state_transform_dirty)
+		{
+			bool have_local_perspective = false;
+			TransformState::LocalPerspective local_perspective;
 
-		bool have_transform = false;
-		Matrix4f transform_value = Matrix4f::Identity();
-		Vector3f transform_origin(pos.x + size.x * 0.5f, pos.y + size.y * 0.5f, 0);
+			bool have_transform = false;
+			Matrix4f transform_value = Matrix4f::Identity();
+			Vector3f transform_origin(pos.x + size.x * 0.5f, pos.y + size.y * 0.5f, 0);
 
-		const Property *transform = GetTransform();
-		if (transform && (transform->unit != Property::KEYWORD || transform->value.Get< int >() != TRANSFORM_NONE))
-		{
-			TransformRef transforms = transform->value.Get< TransformRef >();
-			int n = transforms->GetNumPrimitives();
-			for (int i = 0; i < n; ++i)
+			const Property *transform = GetTransform();
+			if (transform && (transform->unit != Property::KEYWORD || transform->value.Get< int >() != TRANSFORM_NONE))
 			{
-				const Transforms::Primitive &primitive = transforms->GetPrimitive(i);
-
-				if (primitive.ResolvePerspective(local_perspective.distance, *this))
+				TransformRef transforms = transform->value.Get< TransformRef >();
+				int n = transforms->GetNumPrimitives();
+				for (int i = 0; i < n; ++i)
 				{
-					have_local_perspective = true;
-				}
+					const Transforms::Primitive &primitive = transforms->GetPrimitive(i);
 
-				Matrix4f matrix;
-				if (primitive.ResolveTransform(matrix, *this))
-				{
-					transform_value *= matrix;
-					have_transform = true;
+					if (primitive.ResolvePerspective(local_perspective.distance, *this))
+					{
+						have_local_perspective = true;
+					}
+
+					Matrix4f matrix;
+					if (primitive.ResolveTransform(matrix, *this))
+					{
+						transform_value *= matrix;
+						have_transform = true;
+					}
 				}
-			}
 
-			// Compute the transform origin
-			const Property *transform_origin_x = GetTransformOriginX();
-			if (transform_origin_x)
-			{
-				if (transform_origin_x->unit == Property::KEYWORD)
+				// Compute the transform origin
+				const Property *transform_origin_x = GetTransformOriginX();
+				if (transform_origin_x)
 				{
-					switch (transform_origin_x->value.Get< int >())
+					if (transform_origin_x->unit == Property::KEYWORD)
 					{
+						switch (transform_origin_x->value.Get< int >())
+						{
 						case TRANSFORM_ORIGIN_X_LEFT:
 							transform_origin.x = pos.x;
 							break;
@@ -2514,21 +2519,21 @@ void Element::UpdateTransformState()
 						case TRANSFORM_ORIGIN_X_RIGHT:
 							transform_origin.x = pos.x + size.x;
 							break;
+						}
+					}
+					else
+					{
+						transform_origin.x = pos.x + ResolveProperty(transform_origin_x, size.x);
 					}
 				}
-				else
-				{
-					transform_origin.x = pos.x + ResolveProperty(transform_origin_x, size.x);
-				}
-			}
 
-			const Property *transform_origin_y = GetTransformOriginY();
-			if (transform_origin_y)
-			{
-				if (transform_origin_y->unit == Property::KEYWORD)
+				const Property *transform_origin_y = GetTransformOriginY();
+				if (transform_origin_y)
 				{
-					switch (transform_origin_y->value.Get< int >())
+					if (transform_origin_y->unit == Property::KEYWORD)
 					{
+						switch (transform_origin_y->value.Get< int >())
+						{
 						case TRANSFORM_ORIGIN_Y_TOP:
 							transform_origin.y = pos.y;
 							break;
@@ -2540,50 +2545,52 @@ void Element::UpdateTransformState()
 						case TRANSFORM_ORIGIN_Y_BOTTOM:
 							transform_origin.y = pos.y + size.y;
 							break;
+						}
+					}
+					else
+					{
+						transform_origin.y = pos.y + ResolveProperty(transform_origin_y, size.y);
 					}
 				}
-				else
+
+				const Property *transform_origin_z = GetTransformOriginZ();
+				if (transform_origin_z)
 				{
-					transform_origin.y = pos.y + ResolveProperty(transform_origin_y, size.y);
+					transform_origin.z = ResolveProperty(transform_origin_z, Math::Max(size.x, size.y));
 				}
 			}
 
-			const Property *transform_origin_z = GetTransformOriginZ();
-			if (transform_origin_z)
+			if (have_local_perspective && context)
 			{
-				transform_origin.z = ResolveProperty(transform_origin_z, Math::Max(size.x, size.y));
+				local_perspective.view_size = context->GetDimensions();
+				transform_state->SetLocalPerspective(&local_perspective);
+			}
+			else
+			{
+				transform_state->SetLocalPerspective(0);
 			}
-		}
-
-		if (have_local_perspective && context)
-		{
-			local_perspective.view_size = context->GetDimensions();
-			transform_state->SetLocalPerspective(&local_perspective);
-		}
-		else
-		{
-			transform_state->SetLocalPerspective(0);
-		}
 
-		if (have_transform)
-		{
-			// TODO: If we're using the global projection matrix
-			// (perspective < 0), then scale the coordinates from
-			// pixel space to 3D unit space.
-
-			// Transform the Rocket context so that the computed `transform_origin'
-			// lies at the coordinate system origin.
-			transform_value =
-				  Matrix4f::Translate(transform_origin)
-				* transform_value
-				* Matrix4f::Translate(-transform_origin);
-		}
+			if (have_transform)
+			{
+				// TODO: If we're using the global projection matrix
+				// (perspective < 0), then scale the coordinates from
+				// pixel space to 3D unit space.
+
+				// Transform the Rocket context so that the computed `transform_origin'
+				// lies at the coordinate system origin.
+				transform_value =
+					Matrix4f::Translate(transform_origin)
+					* transform_value
+					* Matrix4f::Translate(-transform_origin);
+			}
 
-		transform_state->SetTransform(have_transform ? &transform_value : 0);
+			transform_state->SetTransform(have_transform ? &transform_value : 0);
 
-		transform_state_transform_dirty = false;
+			transform_state_transform_dirty = false;
+		}
 	}
 
+
 	if (transform_state_parent_transform_dirty)
 	{
 		// We need to clean up from the top-most to the bottom-most dirt.
@@ -2591,28 +2598,28 @@ void Element::UpdateTransformState()
 		{
 			parent->UpdateTransformState();
 		}
-	}
 
-	if (transform_state.get())
-	{
-		// Store the parent's new full transform as our parent transform
-		Element *node = 0;
-		Matrix4f parent_transform;
-		for (node = parent; node; node = node->parent)
+		if (transform_state.get())
 		{
-			if (node->GetTransformState() && node->GetTransformState()->GetRecursiveTransform(&parent_transform))
+			// Store the parent's new full transform as our parent transform
+			Element *node = 0;
+			Matrix4f parent_transform;
+			for (node = parent; node; node = node->parent)
 			{
-				transform_state->SetParentRecursiveTransform(&parent_transform);
-				break;
+				if (node->GetTransformState() && node->GetTransformState()->GetRecursiveTransform(&parent_transform))
+				{
+					transform_state->SetParentRecursiveTransform(&parent_transform);
+					break;
+				}
+			}
+			if (!node)
+			{
+				transform_state->SetParentRecursiveTransform(0);
 			}
 		}
-		if (!node)
-		{
-			transform_state->SetParentRecursiveTransform(0);
-		}
-	}
 
-	transform_state_parent_transform_dirty = false;
+		transform_state_parent_transform_dirty = false;
+	}
 
 	// If we neither have a local perspective, nor a perspective nor a
 	// transform, we don't need to keep the large TransformState object

+ 2 - 2
Source/Core/ElementAnimation.cpp

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

+ 11 - 7
Source/Core/ElementDocument.cpp

@@ -296,16 +296,20 @@ void ElementDocument::LoadScript(Stream* ROCKET_UNUSED_PARAMETER(stream), const
 // Updates the layout if necessary.
 void ElementDocument::_UpdateLayout()
 {
-	layout_dirty = false;
+	const int max_updates = 3;
+
 	lock_layout++;
+	for(int i = 0; layout_dirty && i < max_updates; i++)
+	{
+		layout_dirty = false;
 
-	Vector2f containing_block(0, 0);
-	if (GetParentNode() != NULL)
-		containing_block = GetParentNode()->GetBox().GetSize();
+		Vector2f containing_block(0, 0);
+		if (GetParentNode() != NULL)
+			containing_block = GetParentNode()->GetBox().GetSize();
 
-	LayoutEngine layout_engine;
-	layout_engine.FormatElement(this, containing_block);
-	
+		LayoutEngine layout_engine;
+		layout_engine.FormatElement(this, containing_block);
+	}
 	lock_layout--;
 }
 

+ 4 - 4
Source/Core/ElementStyle.cpp

@@ -410,7 +410,7 @@ float ElementStyle::ResolveAngle(const Property * property)
 	return 0.0f;
 }
 
-float ElementStyle::ResolveNumberLengthPercent(const String& name, const Property * property)
+float ElementStyle::ResolveNumericProperty(const String& property_name, const Property * property)
 {
 	if (property->unit & Property::LENGTH)
 	{
@@ -418,15 +418,15 @@ float ElementStyle::ResolveNumberLengthPercent(const String& name, const Propert
 	}
 
 	auto definition = property->definition;
-	if (!definition) definition = StyleSheetSpecification::GetProperty(name);
+	if (!definition) definition = StyleSheetSpecification::GetProperty(property_name);
 	if (!definition) return 0.0f;
 
 	auto relative_target = definition->GetRelativeTarget();
 	
-	return ResolveNumberLengthPercent(property, relative_target);
+	return ResolveNumericProperty(property, relative_target);
 }
 
-float ElementStyle::ResolveNumberLengthPercent(const Property * property, RelativeTarget relative_target)
+float ElementStyle::ResolveNumericProperty(const Property * property, RelativeTarget relative_target)
 {
 	if (property->unit & Property::LENGTH)
 	{

+ 3 - 3
Source/Core/ElementStyle.h

@@ -36,7 +36,7 @@ namespace Core {
 
 class ElementStyleCache;
 
-typedef std::map<String, int> PropCounter;
+typedef std::unordered_map<String, int> PropCounter;
 
 /**
 	Manages an element's style and property information.
@@ -114,11 +114,11 @@ public:
 	static float ResolveAngle(const Property* property);
 
 	/// Resolves a number-length-percentage property to pixels.
-	float ResolveNumberLengthPercent(const String& name, const Property* property);
+	float ResolveNumericProperty(const String& property_name, const Property* property);
 
 	/// Resolves the canonical unit (pixels) from 'number-length-percent' property.
 	/// 'percentage' and 'number' gets multiplied by the size of the specified relative reference.
-	float ResolveNumberLengthPercent(const Property* property, RelativeTarget relative_target);
+	float ResolveNumericProperty(const Property* property, RelativeTarget relative_target);
 
 	/// Resolves one of this element's properties. If the value is a number or px, this is returned. If it's a 
 	/// percentage then it is resolved based on the second argument (the base value).

+ 0 - 1
Source/Core/ElementUtilities.cpp

@@ -148,7 +148,6 @@ int ElementUtilities::GetFontSize(Element* element)
 // Returns an element's line height, if it has a font defined.
 int ElementUtilities::GetLineHeight(Element* element)
 {
-	// TODO: Return float or int?
 	const Property* line_height_property = element->GetLineHeightProperty();
 
 	if (line_height_property->unit & Property::LENGTH && line_height_property->unit != Property::NUMBER)

+ 1 - 1
Source/Core/StyleSheetSpecification.cpp

@@ -236,7 +236,7 @@ void StyleSheetSpecification::RegisterDefaultProperties()
 	RegisterProperty(OVERFLOW_X, "visible", false, true).AddParser("keyword", "visible, hidden, auto, scroll");
 	RegisterProperty(OVERFLOW_Y, "visible", false, true).AddParser("keyword", "visible, hidden, auto, scroll");
 	RegisterShorthand("overflow", "overflow-x, overflow-y", PropertySpecification::REPLICATE);
-	RegisterProperty(CLIP, "auto", true, false).AddParser("keyword", "auto, none").AddParser("length");
+	RegisterProperty(CLIP, "auto", true, false).AddParser("keyword", "auto, none").AddParser("number");
 	RegisterProperty(VISIBILITY, "visible", false, false).AddParser("keyword", "visible, hidden");
 
 	// Need some work on this if we are to include images.

+ 2 - 1
Source/Debugger/CommonSource.h

@@ -30,7 +30,8 @@ static const char* common_rcss =
 "{\n"
 "	font-family: Lacuna;\n"
 "	z-index: top;\n"
-"	font-size: 12;\n"
+"	font-size: 13px;\n"
+"   line-height: 1.4;\n"
 "	color: black;\n"
 "	padding-top: 30px;\n"
 "}\n"

+ 9 - 4
Source/Debugger/InfoSource.h

@@ -28,8 +28,8 @@
 static const char* info_rcss =
 "body\n"
 "{\n"
-"	width: 250px;\n"
-"	min-width: 250px;\n"
+"	width: 320px;\n"
+"	min-width: 320px;\n"
 "	min-height: 150px;\n"
 "	margin-top: 42px;\n"
 "	margin-right: 20px;\n"
@@ -38,11 +38,16 @@ static const char* info_rcss =
 "div#content\n"
 "{\n"
 "   height: auto;\n"
-"	max-height: 500px;\n"
+"	max-height: 650px;\n"
+"}\n"
+"div#content div h2\n"
+"{\n"
+"	padding-left: 5px;\n"
 "}\n"
 "div#content div div\n"
 "{\n"
-"	font-size: 10;\n"
+"	font-size: 12px;\n"
+"	padding-left: 10px;\n"
 "}\n"
 "div#ancestors p:hover,\n"
 "div#children p:hover\n"

+ 2 - 2
Source/Debugger/LogSource.h

@@ -32,8 +32,8 @@ static const char* log_rcss =
 "   height: 300px;\n"
 "	min-width: 200px;\n"
 "	min-height: 150px;\n"
-"	top: 42;\n"
-"	left: 20;\n"
+"	top: 42px;\n"
+"	left: 20px;\n"
 "}\n"
 "div#tools\n"
 "{\n"

+ 1 - 0
Source/Debugger/MenuSource.h

@@ -53,6 +53,7 @@ static const char* menu_rcss =
 "	margin-left: 6px;\n"
 "	display: inline-block;\n"
 "	width: 100px;\n"
+"   line-height: 22px;\n"
 "	text-align: center;\n"
 "}\n"
 "button:hover\n"