#![allow(clippy::collapsible_if)]
mod color;
mod debug_overlay;
mod gradient;
mod kurbo_css;
mod layers;
mod render;
mod sizing;
mod text;
use std::collections::HashMap;
use anyrender::{PaintScene, Scene};
use blitz_dom::{BaseDocument, util::Color};
use render::BlitzDomPainter;
const FONT_EMBOLDEN_ENABLED: bool = cfg!(any(
feature = "font-embolden",
all(feature = "apple-font-embolden", target_os = "macos"),
all(feature = "apple-font-embolden", target_os = "ios"),
));
const SELECTION_COLOR: Color = Color::from_rgb8(180, 213, 255);
type CustomWidgetSceneMap = HashMap<(usize, usize), Scene>;
pub fn paint_scene(
scene: &mut impl PaintScene,
doc: &mut BaseDocument,
scale: f64,
width: u32,
height: u32,
x_offset: u32,
y_offset: u32,
) {
#[allow(unused_mut)]
let mut custom_widget_scenes: CustomWidgetSceneMap = HashMap::new();
#[cfg(feature = "custom-widget")]
build_custom_widget_scenes(&mut custom_widget_scenes, doc, scene, scale);
let generator = BlitzDomPainter::new(
doc,
scale,
width,
height,
x_offset as f64,
y_offset as f64,
&custom_widget_scenes,
);
generator.paint_scene(scene);
}
#[cfg(feature = "custom-widget")]
fn build_custom_widget_scenes(
custom_widget_scenes: &mut CustomWidgetSceneMap,
doc: &mut BaseDocument,
render_ctx: &mut impl anyrender::RenderContext,
scale: f64,
) {
let doc_id = doc.id();
let custom_widget_node_ids = doc.custom_widget_node_ids();
for node_id in custom_widget_node_ids.into_iter() {
if let Some(scene) = process_custom_widget_node(doc, render_ctx, node_id, scale) {
custom_widget_scenes.insert((doc_id, node_id), scene);
}
}
let sub_document_node_ids = doc.sub_document_node_ids();
for node_id in sub_document_node_ids.into_iter() {
if let Some(sub_doc) = doc.get_node_mut(node_id).and_then(|node| node.subdoc_mut()) {
let mut inner = sub_doc.inner_mut();
build_custom_widget_scenes(custom_widget_scenes, &mut inner, render_ctx, scale);
}
}
}
#[cfg(feature = "custom-widget")]
fn process_custom_widget_node(
doc: &mut BaseDocument,
render_ctx: &mut impl anyrender::RenderContext,
node_id: usize,
scale: f64,
) -> Option<Scene> {
use blitz_dom::node::{CustomWidgetStatus, ProxyRenderContext};
let node = doc.get_node_mut(node_id)?;
let width = (node.final_layout.size.width as f64 * scale) as u32;
let height = (node.final_layout.size.height as f64 * scale) as u32;
if width == 0 || height == 0 {
return None;
}
let style = node.stylo_element_data.primary_styles()?;
let element = node.data.downcast_element_mut()?;
let widget_data = element.custom_widget_data_mut()?;
let mut render_ctx = ProxyRenderContext {
inner: render_ctx,
resource_ids: &mut widget_data.active_resource_ids,
};
if widget_data.status == CustomWidgetStatus::Suspended {
widget_data.widget.can_create_surfaces(&mut render_ctx);
widget_data.status = CustomWidgetStatus::Active;
}
let widget_scene = widget_data
.widget
.paint(&mut render_ctx, &style, width, height, scale);
Some(widget_scene)
}