// Updates the position of the document based on the style properties.
void ElementDocument::UpdatePosition()
{
	// We are only positioned relative to our parent, so if we're not parented we may as well bail now.
	if (GetParentNode() == NULL)
		return;

	Vector2f position;
	// Work out our containing block; relative offsets are calculated against it.
	Vector2f containing_block = GetParentNode()->GetBox().GetSize(Box::CONTENT);

	const Property *left = GetLocalProperty(LEFT);
	const Property *right = GetLocalProperty(RIGHT);
	if (left != NULL && left->unit != Property::KEYWORD)
		position.x = ResolveProperty(LEFT, containing_block.x);
	else if (right != NULL && right->unit != Property::KEYWORD)
		position.x = (containing_block.x - GetBox().GetSize(Box::MARGIN).x) - ResolveProperty(RIGHT, containing_block.x);
	else
		position.x = GetBox().GetEdge(Box::MARGIN, Box::LEFT);

	const Property *top = GetLocalProperty(TOP);
	const Property *bottom = GetLocalProperty(BOTTOM);
	if (top != NULL && top->unit != Property::KEYWORD)
		position.y = ResolveProperty(TOP, containing_block.y);
	else if (bottom != NULL && bottom->unit != Property::KEYWORD)
		position.y = (containing_block.y - GetBox().GetSize(Box::MARGIN).y) - ResolveProperty(BOTTOM, containing_block.y);
	else
		position.y = GetBox().GetEdge(Box::MARGIN, Box::TOP);

	SetOffset(position, NULL);
}
// Returns one of this element's properties.
const Property* ElementStyle::GetProperty(const String& name)
{
	const Property* local_property = GetLocalProperty(name);
	if (local_property != NULL)
		return local_property;

	// Fetch the property specification.
	const PropertyDefinition* property = StyleSheetSpecification::GetProperty(name);
	if (property == NULL)
		return NULL;

	// If we can inherit this property, return our parent's property.
	if (property->IsInherited())
	{
		Element* parent = element->GetParentNode();
		while (parent != NULL)
		{
			const Property* parent_property = parent->style->GetLocalProperty(name);
			if (parent_property)
				return parent_property;
			
			parent = parent->GetParentNode();
		}
	}

	// No property available! Return the default value.
	return property->GetDefaultValue();
}
Exemple #3
0
void ElementImage::GenerateGeometry()
{
	// Release the old geometry before specifying the new vertices.
	geometry.Release(true);

	std::vector< Rocket::Core::Vertex >& vertices = geometry.GetVertices();
	std::vector< int >& indices = geometry.GetIndices();

	vertices.resize(4);
	indices.resize(6);

	// Generate the texture coordinates.
	Vector2f texcoords[2];
	if (using_coords)
	{
		Vector2f texture_dimensions((float) texture.GetDimensions(GetRenderInterface()).x, (float) texture.GetDimensions(GetRenderInterface()).y);
		if (texture_dimensions.x == 0)
			texture_dimensions.x = 1;
		if (texture_dimensions.y == 0)
			texture_dimensions.y = 1;

		texcoords[0].x = (float) coords[0] / texture_dimensions.x;
		texcoords[0].y = (float) coords[1] / texture_dimensions.y;

		texcoords[1].x = (float) coords[2] / texture_dimensions.x;
		texcoords[1].y = (float) coords[3] / texture_dimensions.y;
	}
	else
	{
		texcoords[0] = Vector2f(0, 0);
		texcoords[1] = Vector2f(1, 1);
	}

	Colourb colour(255, 255,255,255);
	const Property* property = GetLocalProperty(COLOR);
	if (property)
		colour = property->value.Get<Colourb>();

	Rocket::Core::GeometryUtilities::GenerateQuad(&vertices[0],									// vertices to write to
												  &indices[0],									// indices to write to
												  Vector2f(0, 0),					// origin of the quad
												  GetBox().GetSize(Rocket::Core::Box::CONTENT),	// size of the quad
												  colour,		// colour of the vertices
												  texcoords[0],									// top-left texture coordinate
												  texcoords[1]);								// top-right texture coordinate

	geometry_dirty = false;
}
// Resolves one of this element's properties.
float ElementStyle::ResolveProperty(const String& name, float base_value)
{
	const Property* property = GetProperty(name);
	if (!property)
	{
		ROCKET_ERROR;
		return 0.0f;
	}

	if (property->unit & Property::RELATIVE_UNIT)
	{
		// The calculated value of the font-size property is inherited, so we need to check if this
		// is an inherited property. If so, then we return our parent's font size instead.
		if (name == FONT_SIZE)
		{
			Rocket::Core::Element* parent = element->GetParentNode();
			if (parent == NULL)
				return 0;

			if (GetLocalProperty(FONT_SIZE) == NULL)
				return parent->ResolveProperty(FONT_SIZE, 0);

			// The base value for font size is always the height of *this* element's parent's font.
			base_value = parent->ResolveProperty(FONT_SIZE, 0);
		}

		if (property->unit & Property::PERCENT)
			return base_value * property->value.Get< float >() * 0.01f;
		else if (property->unit & Property::EM)
		{
			// If an em-relative font size is specified, it is expressed relative to the parent's
			// font height.
			if (name == FONT_SIZE)
				return property->value.Get< float >() * base_value;
			else
				return property->value.Get< float >() * ElementUtilities::GetFontSize(element);
		}
	}

	if (property->unit & Property::NUMBER || property->unit & Property::PX)
	{
		return property->value.Get< float >();
	}

	// We're not a numeric property; return 0.
	return 0.0f;
}
// Sets a list of our potentially inherited properties as dirtied by an ancestor.
void ElementStyle::DirtyInheritedProperties(const PropertyNameList& properties)
{
	PropertyNameList inherited_properties;
	for (PropertyNameList::const_iterator i = properties.begin(); i != properties.end(); ++i)
	{
		if (GetLocalProperty((*i)) == NULL)
			inherited_properties.insert(*i);
	}

	if (inherited_properties.empty())
		return;

	// Pass the list of those properties that this element doesn't override onto our children.
	for (int i = 0; i < element->GetNumChildren(true); i++)
		element->GetChild(i)->GetStyle()->DirtyInheritedProperties(inherited_properties);

	element->OnPropertyChange(properties);
}
Exemple #6
0
// Sets a list of our potentially inherited properties as dirtied by an ancestor.
void ElementStyle::DirtyInheritedProperties(const PropertyNameList& properties)
{
	bool clear_em_properties = em_properties != NULL;

	PropertyNameList inherited_properties;
	for (PropertyNameList::const_iterator i = properties.begin(); i != properties.end(); ++i)
	{
		const Property *property = GetLocalProperty((*i));
		if (property == NULL)
		{
			inherited_properties.insert(*i);
			if (!clear_em_properties && em_properties != NULL && em_properties->find((*i)) != em_properties->end()) {
				clear_em_properties = true;
			}
		}
	}

	if (inherited_properties.empty())
		return;

	// clear the list of EM-properties, we will refill it in DirtyEmProperties
	if (clear_em_properties && em_properties != NULL)
	{
		delete em_properties;
		em_properties = NULL;
	}

	// Clear cached inherited properties.
	cache->ClearInherited();

	// Pass the list of those properties that this element doesn't override onto our children.
	for (int i = 0; i < element->GetNumChildren(true); i++)
		element->GetChild(i)->GetStyle()->DirtyInheritedProperties(inherited_properties);

	element->OnPropertyChange(properties);
}
Exemple #7
0
// Resolves one of this element's properties.
float ElementStyle::ResolveProperty(const String& name, float base_value)
{
	const Property* property = GetProperty(name);
	if (!property)
	{
		ROCKET_ERROR;
		return 0.0f;
	}

	if (property->unit & Property::RELATIVE_UNIT)
	{
		// The calculated value of the font-size property is inherited, so we need to check if this
		// is an inherited property. If so, then we return our parent's font size instead.
		if (name == FONT_SIZE)
		{
			// If the rem unit is used, the font-size is inherited directly from the document,
			// otherwise we use the parent's font size.
			if (property->unit & Property::REM)
			{
				Rocket::Core::ElementDocument* owner_document = element->GetOwnerDocument();
				if (owner_document == NULL)
					return 0;

				base_value = element->GetOwnerDocument()->ResolveProperty(FONT_SIZE, 0);
			}
			else
			{
				Rocket::Core::Element* parent = element->GetParentNode();
				if (parent == NULL)
					return 0;

				if (GetLocalProperty(FONT_SIZE) == NULL)
					return parent->ResolveProperty(FONT_SIZE, 0);

				// The base value for font size is always the height of *this* element's parent's font.
				base_value = parent->ResolveProperty(FONT_SIZE, 0);
			}
		}

		if (property->unit & Property::PERCENT)
			return base_value * property->value.Get< float >() * 0.01f;
		else if (property->unit & Property::EM)
		{
			// If an em-relative font size is specified, it is expressed relative to the parent's
			// font height.
			if (name == FONT_SIZE)
				return property->value.Get< float >() * base_value;
			else
				return property->value.Get< float >() * ElementUtilities::GetFontSize(element);
		}
		else if (property->unit & Property::REM)
		{
			// If an rem-relative font size is specified, it is expressed relative to the document's
			// font height.
			if (name == FONT_SIZE)
				return property->value.Get< float >() * base_value;
			else
				return property->value.Get< float >() * ElementUtilities::GetFontSize(element->GetOwnerDocument());
		}
	}

	if (property->unit & Property::NUMBER || property->unit & Property::PX)
	{
		return property->value.Get< float >();
	}
    
    // Values based on pixels-per-inch.
	if (property->unit & Property::PPI_UNIT)
	{
		float inch = property->value.Get< float >() * element->GetRenderInterface()->GetPixelsPerInch();

		if (property->unit & Property::INCH) // inch
			return inch;
		if (property->unit & Property::CM) // centimeter
			return inch / 2.54f;
		if (property->unit & Property::MM) // millimeter
			return inch / 25.4f;
		if (property->unit & Property::PT) // point
			return inch / 72.0f;
		if (property->unit & Property::PC) // pica
			return inch / 6.0f;
	}

	// We're not a numeric property; return 0.
	return 0.0f;
}