@@ -21,6 +21,9 @@ use vello_common::peniko::{Blob, ColorStop, ColorStops, Font};
2121use  vello_common:: pixmap:: Pixmap ; 
2222use  vello_cpu:: RenderMode ; 
2323
24+ #[ cfg( target_arch = "wasm32" ) ]  
25+ include ! ( concat!( env!( "OUT_DIR" ) ,  "/reference_images.rs" ) ) ; 
26+ 
2427static  REFS_PATH :  LazyLock < PathBuf >  = LazyLock :: new ( || { 
2528    PathBuf :: from ( env ! ( "CARGO_MANIFEST_DIR" ) ) . join ( "../vello_sparse_tests/snapshots" ) 
2629} ) ; 
@@ -225,6 +228,7 @@ pub(crate) fn pixmap_to_png(pixmap: Pixmap, width: u32, height: u32) -> Vec<u8>
225228    png_data
226229} 
227230
231+ #[ cfg( not( target_arch = "wasm32" ) ) ]  
228232pub ( crate )  fn  check_ref ( 
229233    ctx :  & impl  Renderer , 
230234    // The name of the test. 
@@ -286,6 +290,116 @@ pub(crate) fn check_ref(
286290    } 
287291} 
288292
293+ #[ cfg( target_arch = "wasm32" ) ]  
294+ pub ( crate )  fn  check_ref ( 
295+     ctx :  & impl  Renderer , 
296+     // The name of the test. 
297+     test_name :  & str , 
298+     // The name of the specific instance of the test that is being run 
299+     // (e.g. test_gpu, test_cpu_u8, etc.) 
300+     specific_name :  & str , 
301+     // Tolerance for pixel differences. 
302+     threshold :  u8 , 
303+     // Whether the test instance is the "gold standard" and should be used 
304+     // for creating reference images. 
305+     is_reference :  bool , 
306+     render_mode :  RenderMode , 
307+ )  { 
308+     assert ! ( !is_reference,  "WASM cannot create new reference images" ) ; 
309+ 
310+     let  pixmap = render_pixmap ( ctx,  render_mode) ; 
311+     let  encoded_image = pixmap_to_png ( pixmap,  ctx. width ( )  as  u32 ,  ctx. height ( )  as  u32 ) ; 
312+     let  actual = load_from_memory ( & encoded_image) . unwrap ( ) . into_rgba8 ( ) ; 
313+ 
314+     let  ref_data = get_reference_image ( test_name) . expect ( "no reference image exists" ) ; 
315+     let  ref_image = load_from_memory ( ref_data) . unwrap ( ) . into_rgba8 ( ) ; 
316+ 
317+     let  diff_image = get_diff ( & ref_image,  & actual,  threshold) ; 
318+     if  let  Some ( ref  img)  = diff_image { 
319+         append_diff_image_to_browser_document ( test_name,  img) ; 
320+         panic ! ( "test didn't match reference image. Scroll to bottom of browser to view diff." ) ; 
321+     } 
322+ } 
323+ 
324+ #[ cfg( target_arch = "wasm32" ) ]  
325+ fn  append_diff_image_to_browser_document ( test_name :  & str ,  diff_image :  & RgbaImage )  { 
326+     use  wasm_bindgen:: JsCast ; 
327+     use  web_sys:: js_sys:: { Array ,  Uint8Array } ; 
328+     use  web_sys:: { Blob ,  BlobPropertyBag ,  HtmlImageElement ,  Url ,  window} ; 
329+ 
330+     let  window = window ( ) . unwrap ( ) ; 
331+     let  document = window. document ( ) . unwrap ( ) ; 
332+     let  body = document. body ( ) . unwrap ( ) ; 
333+ 
334+     // Create container div 
335+     let  container = document. create_element ( "div" ) . unwrap ( ) ; 
336+     container
337+         . set_attribute ( 
338+             "style" , 
339+             "border: 2px solid red; \  
340+ \ 
341+ \ 
342+ \ 
343+ , 
344+         ) 
345+         . unwrap ( ) ; 
346+ 
347+     // Add title 
348+     let  title = document. create_element ( "h3" ) . unwrap ( ) ; 
349+     title. set_text_content ( Some ( & format ! ( "Test Failed: {}" ,  test_name) ) ) ; 
350+     title
351+         . set_attribute ( "style" ,  "color: red; margin-top: 0;" ) 
352+         . unwrap ( ) ; 
353+     container. append_child ( & title) . unwrap ( ) ; 
354+ 
355+     // Convert diff image to PNG 
356+     let  diff_png = { 
357+         let  mut  png_data = Vec :: new ( ) ; 
358+         let  cursor = std:: io:: Cursor :: new ( & mut  png_data) ; 
359+         let  encoder = image:: codecs:: png:: PngEncoder :: new ( cursor) ; 
360+         encoder
361+             . write_image ( 
362+                 diff_image. as_raw ( ) , 
363+                 diff_image. width ( ) , 
364+                 diff_image. height ( ) , 
365+                 image:: ExtendedColorType :: Rgba8 , 
366+             ) 
367+             . unwrap ( ) ; 
368+         png_data
369+     } ; 
370+ 
371+     // Create Uint8Array from bytes 
372+     let  uint8_array = Uint8Array :: new_with_length ( diff_png. len ( )  as  u32 ) ; 
373+     uint8_array. copy_from ( & diff_png) ; 
374+ 
375+     // Create array for Blob constructor 
376+     let  array = Array :: new ( ) ; 
377+     array. push ( & uint8_array. buffer ( ) ) ; 
378+ 
379+     // Create Blob with PNG mime type 
380+     let  mut  blob_property_bag = BlobPropertyBag :: new ( ) ; 
381+     blob_property_bag. type_ ( "image/png" ) ; 
382+     let  blob = Blob :: new_with_u8_array_sequence_and_options ( & array,  & blob_property_bag) . unwrap ( ) ; 
383+ 
384+     // Create object URL 
385+     let  url = Url :: create_object_url_with_blob ( & blob) . unwrap ( ) ; 
386+ 
387+     // Create image element 
388+     let  img = document
389+         . create_element ( "img" ) 
390+         . unwrap ( ) 
391+         . dyn_into :: < HtmlImageElement > ( ) 
392+         . unwrap ( ) ; 
393+     img. set_src ( & url) ; 
394+     img. set_attribute ( "style" ,  "border: 1px solid #ccc; max-width: 100%;" ) 
395+         . unwrap ( ) ; 
396+     img. set_attribute ( "title" ,  "Expected | Diff | Actual" ) 
397+         . unwrap ( ) ; 
398+ 
399+     container. append_child ( & img) . unwrap ( ) ; 
400+     body. append_child ( & container) . unwrap ( ) ; 
401+ } 
402+ 
289403fn  get_diff ( 
290404    expected_image :  & RgbaImage , 
291405    actual_image :  & RgbaImage , 
0 commit comments