1use crate::node::{Node, NodeData};
2use color::{AlphaColor, Srgb};
3use style::color::AbsoluteColor;
4
5pub type Color = AlphaColor<Srgb>;
6
7#[cfg(feature = "svg")]
8use std::sync::{Arc, LazyLock};
9#[cfg(feature = "svg")]
10use usvg::fontdb;
11#[cfg(feature = "svg")]
12pub(crate) static FONT_DB: LazyLock<Arc<fontdb::Database>> = LazyLock::new(|| {
13 let mut db = fontdb::Database::new();
14 db.load_system_fonts();
15 Arc::new(db)
16});
17
18#[derive(Clone, Debug)]
19pub enum ImageType {
20 Image,
21 Background(usize),
22}
23
24pub fn walk_tree(indent: usize, node: &Node) {
26 if let NodeData::Text(data) = &node.data {
28 if data.content.chars().all(|c| c.is_ascii_whitespace()) {
29 return;
30 }
31 }
32
33 print!("{}", " ".repeat(indent));
34 let id = node.id;
35 match &node.data {
36 NodeData::Document => println!("#Document {id}"),
37
38 NodeData::Text(data) => {
39 if data.content.chars().all(|c| c.is_ascii_whitespace()) {
40 println!("{id} #text: <whitespace>");
41 } else {
42 let content = data.content.trim();
43 if content.len() > 10 {
44 println!(
45 "#text {id}: {}...",
46 content
47 .split_at(content.char_indices().take(10).last().unwrap().0)
48 .0
49 .escape_default()
50 )
51 } else {
52 println!("#text {id}: {}", data.content.trim().escape_default())
53 }
54 }
55 }
56
57 NodeData::Comment => println!("<!-- COMMENT {id} -->"),
58
59 NodeData::AnonymousBlock(_) => println!("{id} AnonymousBlock"),
60
61 NodeData::Element(data) => {
62 print!("<{} {id}", data.name.local);
63 for attr in data.attrs.iter() {
64 print!(" {}=\"{}\"", attr.name.local, attr.value);
65 }
66 if !node.children.is_empty() {
67 println!(">");
68 } else {
69 println!("/>");
70 }
71 } }
78
79 if !node.children.is_empty() {
80 for child_id in node.children.iter() {
81 walk_tree(indent + 2, node.with(*child_id));
82 }
83
84 if let NodeData::Element(data) = &node.data {
85 println!("{}</{}>", " ".repeat(indent), data.name.local);
86 }
87 }
88}
89
90#[cfg(feature = "svg")]
91pub(crate) fn parse_svg(source: &[u8]) -> Result<usvg::Tree, usvg::Error> {
92 let options = usvg::Options {
93 fontdb: Arc::clone(&*FONT_DB),
94 ..Default::default()
95 };
96
97 let tree = usvg::Tree::from_data(source, &options)?;
98 Ok(tree)
99}
100
101pub trait ToColorColor {
102 fn as_color_color(&self) -> Color;
104}
105impl ToColorColor for AbsoluteColor {
106 fn as_color_color(&self) -> Color {
107 Color::new(
108 *self
109 .to_color_space(style::color::ColorSpace::Srgb)
110 .raw_components(),
111 )
112 }
113}
114
115#[macro_export]
118macro_rules! qual_name {
119 ($local:tt $(, $ns:ident)?) => {
120 $crate::QualName {
121 prefix: None,
122 ns: $crate::ns!($($ns)?),
123 local: $crate::local_name!($local),
124 }
125 };
126}