@@ -21,9 +21,14 @@ 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+ 
27+ #[ cfg( not( target_arch = "wasm32" ) ) ]  
2428static  REFS_PATH :  LazyLock < PathBuf >  = LazyLock :: new ( || { 
2529    PathBuf :: from ( env ! ( "CARGO_MANIFEST_DIR" ) ) . join ( "../vello_sparse_tests/snapshots" ) 
2630} ) ; 
31+ #[ cfg( not( target_arch = "wasm32" ) ) ]  
2732static  DIFFS_PATH :  LazyLock < PathBuf >  =
2833    LazyLock :: new ( || PathBuf :: from ( env ! ( "CARGO_MANIFEST_DIR" ) ) . join ( "../vello_sparse_tests/diffs" ) ) ; 
2934
@@ -225,6 +230,7 @@ pub(crate) fn pixmap_to_png(pixmap: Pixmap, width: u32, height: u32) -> Vec<u8>
225230    png_data
226231} 
227232
233+ #[ cfg( not( target_arch = "wasm32" ) ) ]  
228234pub ( crate )  fn  check_ref ( 
229235    ctx :  & impl  Renderer , 
230236    // The name of the test. 
@@ -286,6 +292,102 @@ pub(crate) fn check_ref(
286292    } 
287293} 
288294
295+ #[ cfg( target_arch = "wasm32" ) ]  
296+ pub ( crate )  fn  check_ref ( 
297+     ctx :  & impl  Renderer , 
298+     // The name of the test. 
299+     test_name :  & str , 
300+     _:  & str , 
301+     // Tolerance for pixel differences. 
302+     threshold :  u8 , 
303+     // Must be `false` on `wasm32` as reference image cannot be written to filesystem. 
304+     is_reference :  bool , 
305+     render_mode :  RenderMode , 
306+ )  { 
307+     assert ! ( !is_reference,  "WASM cannot create new reference images" ) ; 
308+ 
309+     let  pixmap = render_pixmap ( ctx,  render_mode) ; 
310+     let  encoded_image = pixmap_to_png ( pixmap,  ctx. width ( )  as  u32 ,  ctx. height ( )  as  u32 ) ; 
311+     let  actual = load_from_memory ( & encoded_image) . unwrap ( ) . into_rgba8 ( ) ; 
312+ 
313+     let  ref_data = get_reference_image ( test_name) . expect ( "no reference image exists" ) ; 
314+     let  ref_image = load_from_memory ( ref_data) . unwrap ( ) . into_rgba8 ( ) ; 
315+ 
316+     let  diff_image = get_diff ( & ref_image,  & actual,  threshold) ; 
317+     if  let  Some ( ref  img)  = diff_image { 
318+         append_diff_image_to_browser_document ( test_name,  img) ; 
319+         panic ! ( "test didn't match reference image. Scroll to bottom of browser to view diff." ) ; 
320+     } 
321+ } 
322+ 
323+ #[ cfg( target_arch = "wasm32" ) ]  
324+ fn  append_diff_image_to_browser_document ( test_name :  & str ,  diff_image :  & RgbaImage )  { 
325+     use  wasm_bindgen:: JsCast ; 
326+     use  web_sys:: js_sys:: { Array ,  Uint8Array } ; 
327+     use  web_sys:: { Blob ,  BlobPropertyBag ,  HtmlImageElement ,  Url ,  window} ; 
328+ 
329+     let  window = window ( ) . unwrap ( ) ; 
330+     let  document = window. document ( ) . unwrap ( ) ; 
331+     let  body = document. body ( ) . unwrap ( ) ; 
332+ 
333+     let  container = document. create_element ( "div" ) . unwrap ( ) ; 
334+     container
335+         . set_attribute ( 
336+             "style" , 
337+             "border: 2px solid red; \  
338+ \ 
339+ \ 
340+ \ 
341+ , 
342+         ) 
343+         . unwrap ( ) ; 
344+ 
345+     let  title = document. create_element ( "h3" ) . unwrap ( ) ; 
346+     title. set_text_content ( Some ( & format ! ( "Test Failed: {}" ,  test_name) ) ) ; 
347+     title
348+         . set_attribute ( "style" ,  "color: red; margin-top: 0;" ) 
349+         . unwrap ( ) ; 
350+     container. append_child ( & title) . unwrap ( ) ; 
351+ 
352+     let  diff_png = { 
353+         let  mut  png_data = Vec :: new ( ) ; 
354+         let  cursor = std:: io:: Cursor :: new ( & mut  png_data) ; 
355+         let  encoder = image:: codecs:: png:: PngEncoder :: new ( cursor) ; 
356+         encoder
357+             . write_image ( 
358+                 diff_image. as_raw ( ) , 
359+                 diff_image. width ( ) , 
360+                 diff_image. height ( ) , 
361+                 image:: ExtendedColorType :: Rgba8 , 
362+             ) 
363+             . unwrap ( ) ; 
364+         png_data
365+     } ; 
366+ 
367+     let  uint8_array = Uint8Array :: new_with_length ( diff_png. len ( )  as  u32 ) ; 
368+     uint8_array. copy_from ( & diff_png) ; 
369+     let  array = Array :: new ( ) ; 
370+     array. push ( & uint8_array. buffer ( ) ) ; 
371+     let  mut  blob_property_bag = BlobPropertyBag :: new ( ) ; 
372+     blob_property_bag. set_type ( "image/png" ) ; 
373+     let  blob = Blob :: new_with_u8_array_sequence_and_options ( & array,  & blob_property_bag) . unwrap ( ) ; 
374+     let  url = Url :: create_object_url_with_blob ( & blob) . unwrap ( ) ; 
375+ 
376+     let  img = document
377+         . create_element ( "img" ) 
378+         . unwrap ( ) 
379+         . dyn_into :: < HtmlImageElement > ( ) 
380+         . unwrap ( ) ; 
381+     img. set_src ( & url) ; 
382+     img. set_attribute ( "style" ,  "border: 1px solid #ccc; max-width: 100%;" ) 
383+         . unwrap ( ) ; 
384+     img. set_attribute ( "title" ,  "Expected | Diff | Actual" ) 
385+         . unwrap ( ) ; 
386+ 
387+     container. append_child ( & img) . unwrap ( ) ; 
388+     body. append_child ( & container) . unwrap ( ) ; 
389+ } 
390+ 
289391fn  get_diff ( 
290392    expected_image :  & RgbaImage , 
291393    actual_image :  & RgbaImage , 
0 commit comments