use crate::{Bounds, DomNode, DomNodeKind, DomStyle, Hsla, Pixels, px};
pub(crate) fn css_color(color: Hsla) -> String {
let rgba = color.to_rgb();
let r = (rgba.r * 255.0).round() as u8;
let g = (rgba.g * 255.0).round() as u8;
let b = (rgba.b * 255.0).round() as u8;
format!("rgba({},{},{},{})", r, g, b, rgba.a)
}
pub(crate) fn svg_data_uri(svg: &str) -> String {
format!(
"data:image/svg+xml;base64,{}",
base64_encode(svg.as_bytes())
)
}
fn base64_encode(input: &[u8]) -> String {
const TABLE: &[u8; 64] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
let mut out = String::with_capacity(input.len().div_ceil(3) * 4);
for chunk in input.chunks(3) {
let b0 = chunk[0];
let b1 = *chunk.get(1).unwrap_or(&0);
let b2 = *chunk.get(2).unwrap_or(&0);
let n = ((b0 as u32) << 16) | ((b1 as u32) << 8) | (b2 as u32);
out.push(TABLE[(n >> 18) as usize & 63] as char);
out.push(TABLE[(n >> 12) as usize & 63] as char);
out.push(if chunk.len() > 1 {
TABLE[(n >> 6) as usize & 63] as char
} else {
'='
});
out.push(if chunk.len() > 2 {
TABLE[n as usize & 63] as char
} else {
'='
});
}
out
}
pub(crate) fn svg_img_node(bounds: Bounds<Pixels>, svg: String) -> Option<DomNode> {
if bounds.size.width <= px(0.0) || bounds.size.height <= px(0.0) {
return None;
}
Some(DomNode {
kind: DomNodeKind::Element {
tag: "img",
attrs: vec![
("src".into(), svg_data_uri(&svg)),
("draggable".into(), "false".into()),
],
children: Vec::new(),
},
style: DomStyle::from_bounds(bounds),
scroll_handle: None,
})
}