// 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(); }
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); }
// 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); }
// 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; }