use super::{tiles, RenderState, SurfaceId}; use skia_safe::{self as skia, Rect}; #[cfg(target_arch = "wasm32")] use crate::run_script; const DEBUG_SCALE: f32 = 0.2; fn get_debug_rect(rect: Rect) -> Rect { skia::Rect::from_xywh( 100. + rect.x() * DEBUG_SCALE, 100. + rect.y() * DEBUG_SCALE, rect.width() * DEBUG_SCALE, rect.height() * DEBUG_SCALE, ) } #[allow(dead_code)] fn render_debug_view(render_state: &mut RenderState) { let mut paint = skia::Paint::default(); paint.set_style(skia::PaintStyle::Stroke); paint.set_color(skia::Color::GREEN); paint.set_stroke_width(1.); let rect = get_debug_rect(render_state.viewbox.area); render_state .surfaces .canvas(SurfaceId::Debug) .draw_rect(rect, &paint); } #[allow(dead_code)] pub fn render_debug_cache_surface(render_state: &mut RenderState) { let canvas = render_state.surfaces.canvas(SurfaceId::Debug); canvas.save(); canvas.scale((0.1, 0.1)); render_state .surfaces .draw_into(SurfaceId::Cache, SurfaceId::Debug, None); render_state.surfaces.canvas(SurfaceId::Debug).restore(); } pub fn render_wasm_label(render_state: &mut RenderState) { let canvas = render_state.surfaces.canvas(SurfaceId::Target); let skia::ISize { width, height } = canvas.base_layer_size(); let mut paint = skia::Paint::default(); paint.set_color(skia::Color::GRAY); let str = if render_state.options.is_debug_visible() { "WASM RENDERER (DEBUG)" } else { "WASM RENDERER" }; let (scalar, _) = render_state.fonts.debug_font().measure_str(str, None); let p = skia::Point::new(width as f32 - 25.0 - scalar, height as f32 - 25.0); let debug_font = render_state.fonts.debug_font(); canvas.draw_str(str, p, debug_font, &paint); } #[allow(dead_code)] pub fn render_debug_tiles_for_viewbox(render_state: &mut RenderState) { let tiles::TileRect(sx, sy, ex, ey) = render_state.tile_viewbox.interest_rect; let canvas = render_state.surfaces.canvas(SurfaceId::Debug); let mut paint = skia::Paint::default(); paint.set_color(skia::Color::RED); let str_rect = format!("{} {} {} {}", sx, sy, ex, ey); let debug_font = render_state.fonts.debug_font(); canvas.draw_str(str_rect, skia::Point::new(100.0, 150.0), debug_font, &paint); } // Renders the tiles in the viewbox #[allow(dead_code)] pub fn render_debug_viewbox_tiles(render_state: &mut RenderState) { let scale = render_state.get_scale(); let canvas = render_state.surfaces.canvas(SurfaceId::Debug); let mut paint = skia::Paint::default(); paint.set_style(skia::PaintStyle::Stroke); paint.set_color(skia::Color::MAGENTA); paint.set_stroke_width(1.); let tile_size = tiles::get_tile_size(scale); let tiles::TileRect(sx, sy, ex, ey) = tiles::get_tiles_for_rect(render_state.viewbox.area, tile_size); let str_rect = format!("{} {} {} {}", sx, sy, ex, ey); let debug_font = render_state.fonts.debug_font(); canvas.draw_str(str_rect, skia::Point::new(100.0, 100.0), debug_font, &paint); let tile_size = tiles::get_tile_size(scale); for y in sy..=ey { for x in sx..=ex { let rect = Rect::from_xywh( x as f32 * tile_size, y as f32 * tile_size, tile_size, tile_size, ); let debug_rect = get_debug_rect(rect); let p = skia::Point::new(debug_rect.x(), debug_rect.y() - 1.); let str = format!("{}:{}", x, y); let debug_font = render_state.fonts.debug_font(); paint.set_style(skia::PaintStyle::Fill); canvas.draw_str(str, p, debug_font, &paint); canvas.draw_rect(debug_rect, &paint); } } } pub fn render(render_state: &mut RenderState) { // DEBUG VIEWBOX - green rect - buggy? // render_debug_view(render_state); // DEBUG VIEWBOX TILES - magenta - buggy? // render_debug_viewbox_tiles(render_state); // DEBUG CACHE SURFACE - noisy - ? // render_debug_cache_surface(render_state); render_state.surfaces.draw_into( SurfaceId::Debug, SurfaceId::Target, Some(&skia::Paint::default()), ); } pub fn render_workspace_current_tile( render_state: &mut RenderState, prefix: String, tile: tiles::Tile, rect: skia::Rect, ) { let canvas = render_state.surfaces.canvas(SurfaceId::Debug); let mut p = skia::Paint::default(); p.set_stroke_width(2.); p.set_style(skia::PaintStyle::Stroke); canvas.draw_rect(rect, &p); let tile_position_origin = skia::Point::new(rect.x() + 10., rect.y() + 20.); p.set_style(skia::PaintStyle::Fill); let str = format!("{prefix} {}:{}", tile.0, tile.1); let mut debug_font = render_state.fonts.debug_font().clone(); debug_font.set_size(16.); canvas.draw_str(str, tile_position_origin, &debug_font, &p); } pub fn render_debug_shape( render_state: &mut RenderState, shape_selrect: Option, shape_extrect: Option, ) { let canvas = render_state.surfaces.canvas(SurfaceId::Debug); let mut paint = skia::Paint::default(); paint.set_style(skia::PaintStyle::Stroke); paint.set_color(skia::Color::RED); paint.set_stroke_width(1.); if let Some(rect) = shape_selrect { canvas.draw_rect(rect, &paint); } if let Some(rect) = shape_extrect { paint.set_color(skia::Color::BLUE); canvas.draw_rect(rect, &paint); } } #[cfg(target_arch = "wasm32")] #[allow(dead_code)] pub fn console_debug_surface(render_state: &mut RenderState, id: SurfaceId) { let base64_image = render_state.surfaces.base64_snapshot(id); run_script!(format!("console.log('%c ', 'font-size: 1px; background: url(data:image/png;base64,{base64_image}) no-repeat; padding: 100px; background-size: contain;')")) } #[allow(dead_code)] #[cfg(target_arch = "wasm32")] pub fn console_debug_surface_rect(render_state: &mut RenderState, id: SurfaceId, rect: skia::Rect) { let int_rect = skia::IRect::from_ltrb( rect.left as i32, rect.top as i32, rect.right as i32, rect.bottom as i32, ); let base64_image = render_state.surfaces.base64_snapshot_rect(id, int_rect); if let Some(base64_image) = base64_image { run_script!(format!("console.log('%c ', 'font-size: 1px; background: url(data:image/png;base64,{base64_image}) no-repeat; padding: 100px; background-size: contain;')")) } }