Skip to content

Commit

Permalink
Merge pull request #584 from Sharktheone/css/inheritance
Browse files Browse the repository at this point in the history
Css/inheritance
  • Loading branch information
Sharktheone authored Sep 7, 2024
2 parents 54f904f + b96d10a commit f7f1e26
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 56 deletions.
47 changes: 17 additions & 30 deletions crates/gosub_renderer/src/draw.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,33 +250,6 @@ where
}

fn render_node(&mut self, id: NodeId, pos: &mut Point) -> anyhow::Result<()> {
let parent = self.drawer.tree.parent_id(id).unwrap_or(id);

let parent_color = self
.drawer
.tree
.get_node_mut(parent)
.ok_or(anyhow!("Node {id} not found"))?
.properties
.get("color")
.and_then(|prop| {
prop.compute_value();

match &prop.actual {
CssValue::Color(color) => Some(*color),
CssValue::String(color) => Some(RgbColor::from(color.as_str())),
_ => None,
}
})
.unwrap_or(RgbColor::default()); //HACK: this needs to be removed

let parent_color = B::Color::rgba(
parent_color.r as u8,
parent_color.g as u8,
parent_color.b as u8,
parent_color.a as u8,
);

let node = self
.drawer
.tree
Expand Down Expand Up @@ -313,14 +286,13 @@ where
}
}

render_text::<B, L>(node, parent_color, self.scene, pos);
render_text::<B, L>(node, self.scene, pos);
Ok(())
}
}

fn render_text<B: RenderBackend, L: Layouter>(
node: &RenderTreeNode<L>,
color: B::Color,
node: &mut RenderTreeNode<L>,
scene: &mut B::Scene,
pos: &Point,
) where
Expand All @@ -335,6 +307,21 @@ fn render_text<B: RenderBackend, L: Layouter>(
// return;
// }

let color = node
.properties
.get("color")
.and_then(|prop| {
prop.compute_value();

match &prop.actual {
CssValue::Color(color) => Some(*color),
CssValue::String(color) => Some(RgbColor::from(color.as_str())),
_ => None,
}
})
.map(|color| Color::rgba(color.r as u8, color.g as u8, color.b as u8, color.a as u8))
.unwrap_or(Color::BLACK);

if let RenderNodeData::Text(ref text) = node.data {
let Some(layout) = text.layout.as_ref() else {
warn!("No layout for text node");
Expand Down
53 changes: 52 additions & 1 deletion crates/gosub_styling/src/render_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ use std::fmt::{Debug, Formatter};

use crate::property_definitions::get_css_definitions;
use crate::shorthands::FixList;
use crate::styling::{match_selector, CssProperties, CssProperty, DeclarationProperty};
use crate::styling::{
match_selector, prop_is_inherit, CssProperties, CssProperty, DeclarationProperty,
};
use log::warn;

use gosub_css3::stylesheet::{CssDeclaration, CssOrigin, CssSelector, CssStylesheet, CssValue};
Expand Down Expand Up @@ -348,13 +350,62 @@ impl<L: Layouter> RenderTree<L> {

self.remove_unrenderable_nodes();

self.resolve_inheritance(self.root, &Vec::new());

if L::COLLAPSE_INLINE {
self.collapse_inline(self.root);
}

// self.print_tree();
}

fn resolve_inheritance(&mut self, node_id: NodeId, inherit_props: &Vec<(String, CssValue)>) {
let Some(current_node) = self.get_node(node_id) else {
return;
};

for prop in inherit_props {
current_node
.properties
.properties
.entry(prop.0.clone())
.or_insert_with(|| {
let mut p = CssProperty::new(prop.0.as_str());

p.inherited = prop.1.clone();

p
});
}

let mut inherit_props = inherit_props.clone();

'props: for (name, prop) in &mut current_node.properties.properties {
prop.compute_value();

let value = prop.actual.clone();

if prop_is_inherit(name) {
for (k, v) in &mut inherit_props {
if k == name {
*v = value;
continue 'props;
}
}

inherit_props.push((name.clone(), value));
}
}

let Some(children) = self.get_children(node_id) else {
return;
};

for child in children.clone() {
self.resolve_inheritance(child, &inherit_props);
}
}

/// Removes all unrenderable nodes from the render tree
fn remove_unrenderable_nodes(&mut self) {
// There are more elements that are not renderable, but for now we only remove the most common ones
Expand Down
41 changes: 18 additions & 23 deletions crates/gosub_styling/src/styling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use core::fmt::Debug;
use std::cmp::Ordering;
use std::collections::HashMap;

use crate::property_definitions::get_css_definitions;
use crate::property_definitions::{get_css_definitions, CSS_DEFINITIONS};
use gosub_css3::stylesheet::{
CssOrigin, CssSelector, CssSelectorPart, CssSelectorType, CssValue, MatcherType, Specificity,
};
Expand Down Expand Up @@ -273,6 +273,7 @@ pub struct CssProperty {
pub used: CssValue,
// Actual value used in the rendering (after rounding, clipping etc.)
pub actual: CssValue,
pub inherited: CssValue,
}

impl CssProperty {
Expand All @@ -286,6 +287,7 @@ impl CssProperty {
computed: CssValue::None,
used: CssValue::None,
actual: CssValue::None,
inherited: CssValue::None,
}
}

Expand Down Expand Up @@ -342,13 +344,8 @@ impl CssProperty {
return self.specified.clone();
}

if self.is_inheritable() {
todo!("inheritable properties")
// while let Some(parent) = self.get_parent() {
// if let Some(parent_value) = parent {
// return parent_value.find_computed_value();
// }
// }
if self.inherited != CssValue::None {
return self.inherited.clone();
}

self.get_initial_value().unwrap_or(CssValue::None)
Expand All @@ -368,15 +365,6 @@ impl CssProperty {
}
}

// // Returns true when the property is inheritable, false otherwise
fn is_inheritable(&self) -> bool {
let defs = get_css_definitions();
match defs.find_property(&self.name) {
Some(def) => def.inherited(),
None => false,
}
}

// /// Returns true if the given property is a shorthand property (ie: border, margin etc)
pub fn is_shorthand(&self) -> bool {
let defs = get_css_definitions();
Expand Down Expand Up @@ -435,6 +423,13 @@ impl CssProperties {
}
}

pub fn prop_is_inherit(name: &str) -> bool {
CSS_DEFINITIONS
.find_property(name)
.map(|def| def.inherited)
.unwrap_or(false)
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down Expand Up @@ -480,7 +475,7 @@ mod tests {
assert!(prop.is_shorthand());
assert_eq!(prop.name, "border");
assert_eq!(prop.get_initial_value(), Some(CssValue::None));
assert!(!prop.is_inheritable());
assert!(!prop_is_inherit(&prop.name));
}

#[test]
Expand All @@ -499,7 +494,7 @@ mod tests {
assert!(!prop.is_shorthand());
assert_eq!(prop.name, "color");
assert_eq!(prop.get_initial_value(), Some(&CssValue::None).cloned());
assert!(prop.is_inheritable());
assert!(prop_is_inherit(&prop.name));
}

#[test]
Expand Down Expand Up @@ -571,16 +566,16 @@ mod tests {
#[test]
fn is_inheritable() {
let prop = CssProperty::new("border");
assert!(!prop.is_inheritable());
assert!(!prop_is_inherit(&prop.name));

let prop = CssProperty::new("color");
assert!(prop.is_inheritable());
assert!(prop_is_inherit(&prop.name));

let prop = CssProperty::new("font");
assert!(prop.is_inheritable());
assert!(prop_is_inherit(&prop.name));

let prop = CssProperty::new("border-top-color");
assert!(!prop.is_inheritable());
assert!(!prop_is_inherit(&prop.name));
}

#[test]
Expand Down
2 changes: 0 additions & 2 deletions crates/gosub_taffy/src/compute/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,8 +305,6 @@ pub fn compute_inline_layout<LT: LayoutTree<TaffyLayouter>>(

let run_y = run.baseline();

println!("run_y: {}", run_y);

if current_node_id.into() == 161 || current_node_id.into() == 163 {
println!("current_node_id: {:?}", current_node_id.into());
println!("first glyph: {:?}", glyphs.get(2));
Expand Down

0 comments on commit f7f1e26

Please sign in to comment.