use crate::node::{Node, NodeData};
use color::{AlphaColor, Srgb};
use style::color::AbsoluteColor;
pub type Color = AlphaColor<Srgb>;
#[cfg(feature = "svg")]
use std::sync::{Arc, LazyLock};
#[cfg(feature = "svg")]
use usvg::fontdb;
#[cfg(feature = "svg")]
pub(crate) static FONT_DB: LazyLock<Arc<fontdb::Database>> = LazyLock::new(|| {
let mut db = fontdb::Database::new();
db.load_system_fonts();
Arc::new(db)
});
#[derive(Clone, Debug)]
pub enum ImageType {
Image,
Background(usize),
}
#[derive(Clone, Debug, Copy, Eq, PartialEq)]
pub struct Point<T> {
pub x: T,
pub y: T,
}
impl Point<f64> {
pub const ZERO: Self = Point { x: 0.0, y: 0.0 };
}
pub fn walk_tree(indent: usize, node: &Node) {
if let NodeData::Text(data) = &node.data {
if data.content.chars().all(|c| c.is_ascii_whitespace()) {
return;
}
}
print!("{}", " ".repeat(indent));
let id = node.id;
match &node.data {
NodeData::Document => println!("#Document {id}"),
NodeData::Text(data) => {
if data.content.chars().all(|c| c.is_ascii_whitespace()) {
println!("{id} #text: <whitespace>");
} else {
let content = data.content.trim();
if content.len() > 10 {
println!(
"#text {id}: {}...",
content
.split_at(content.char_indices().take(10).last().unwrap().0)
.0
.escape_default()
)
} else {
println!("#text {id}: {}", data.content.trim().escape_default())
}
}
}
NodeData::Comment => println!("<!-- COMMENT {id} -->"),
NodeData::AnonymousBlock(_) => println!("{id} AnonymousBlock"),
NodeData::Element(data) => {
print!("<{} {id}", data.name.local);
for attr in data.attrs.iter() {
print!(" {}=\"{}\"", attr.name.local, attr.value);
}
if !node.children.is_empty() {
println!(">");
} else {
println!("/>");
}
} }
if !node.children.is_empty() {
for child_id in node.children.iter() {
walk_tree(indent + 2, node.with(*child_id));
}
if let NodeData::Element(data) = &node.data {
println!("{}</{}>", " ".repeat(indent), data.name.local);
}
}
}
#[cfg(feature = "svg")]
pub(crate) fn parse_svg(source: &[u8]) -> Result<usvg::Tree, usvg::Error> {
let options = usvg::Options {
fontdb: Arc::clone(&*FONT_DB),
..Default::default()
};
let tree = usvg::Tree::from_data(source, &options)?;
Ok(tree)
}
pub trait ToColorColor {
fn as_color_color(&self) -> Color;
}
impl ToColorColor for AbsoluteColor {
fn as_color_color(&self) -> Color {
Color::new(
*self
.to_color_space(style::color::ColorSpace::Srgb)
.raw_components(),
)
}
}
#[macro_export]
macro_rules! qual_name {
($local:tt $(, $ns:ident)?) => {
$crate::QualName {
prefix: None,
ns: $crate::ns!($($ns)?),
local: $crate::local_name!($local),
}
};
}