use crate::css_values::types::length::*;
pub struct ResolveContext {
pub font_size: f32,
pub root_font_size: f32,
pub viewport_w: f32,
pub viewport_h: f32,
}
impl Default for ResolveContext {
fn default() -> Self {
Self {
font_size: 16.0,
root_font_size: 16.0,
viewport_w: 1920.0,
viewport_h: 1080.0,
}
}
}
pub fn resolve_length(length: &Length, ctx: &ResolveContext) -> f32 {
match length {
Length::Px(v) => *v as f32,
Length::Em(v) => *v as f32 * ctx.font_size,
Length::Rem(v) => *v as f32 * ctx.root_font_size,
Length::Vw(v) => *v as f32 * ctx.viewport_w / 100.0,
Length::Vh(v) => *v as f32 * ctx.viewport_h / 100.0,
Length::Vmin(v) => *v as f32 * ctx.viewport_w.min(ctx.viewport_h) / 100.0,
Length::Vmax(v) => *v as f32 * ctx.viewport_w.max(ctx.viewport_h) / 100.0,
Length::Cm(v) => *v as f32 * 96.0 / 2.54,
Length::Mm(v) => *v as f32 * 96.0 / 25.4,
Length::In(v) => *v as f32 * 96.0,
Length::Pt(v) => *v as f32 * 4.0 / 3.0,
Length::Pc(v) => *v as f32 * 16.0,
Length::Ch(v) => *v as f32 * ctx.font_size * 0.5,
Length::Ex(v) => *v as f32 * ctx.font_size * 0.5,
Length::Zero => 0.0,
}
}
pub fn resolve_length_percentage(
lp: &LengthPercentage,
ctx: &ResolveContext,
reference_size: f32,
) -> f32 {
match lp {
LengthPercentage::Length(l) => resolve_length(l, ctx),
LengthPercentage::Percentage(p) => *p as f32 / 100.0 * reference_size,
}
}
pub fn resolve_length_percentage_auto(
lpa: &LengthPercentageAuto,
ctx: &ResolveContext,
reference_size: f32,
) -> Option<f32> {
match lpa {
LengthPercentageAuto::Length(l) => Some(resolve_length(l, ctx)),
LengthPercentageAuto::Percentage(p) => Some(*p as f32 / 100.0 * reference_size),
LengthPercentageAuto::Auto => None,
}
}
#[cfg(test)]
mod tests {
use super::*;
fn ctx() -> ResolveContext {
ResolveContext::default()
}
#[test]
fn resolve_px() {
assert_eq!(resolve_length(&Length::Px(100.0), &ctx()), 100.0);
}
#[test]
fn resolve_em() {
let mut c = ctx();
c.font_size = 20.0;
assert_eq!(resolve_length(&Length::Em(2.0), &c), 40.0);
}
#[test]
fn resolve_rem() {
let mut c = ctx();
c.root_font_size = 18.0;
assert_eq!(resolve_length(&Length::Rem(1.5), &c), 27.0);
}
#[test]
fn resolve_vw() {
assert_eq!(resolve_length(&Length::Vw(50.0), &ctx()), 960.0);
}
#[test]
fn resolve_percentage() {
let lp = LengthPercentage::Percentage(50.0);
assert_eq!(resolve_length_percentage(&lp, &ctx(), 200.0), 100.0);
}
#[test]
fn resolve_auto() {
let lpa = LengthPercentageAuto::Auto;
assert_eq!(resolve_length_percentage_auto(&lpa, &ctx(), 200.0), None);
}
#[test]
fn resolve_zero() {
assert_eq!(resolve_length(&Length::Zero, &ctx()), 0.0);
}
}