1
1
use cosmic_text:: { Attrs , Buffer , FontSystem , Metrics , Shaping } ;
2
2
use fontdb:: Source ;
3
- use image:: { load_from_memory, Rgba } ;
3
+ use image:: { load_from_memory, Rgba , RgbaImage } ;
4
4
use krilla:: document:: Document ;
5
5
use krilla:: rgb:: Rgb ;
6
6
use krilla:: serialize:: SerializeSettings ;
@@ -36,6 +36,10 @@ pub fn save_refs(name: &str, renderer: &Renderer, document: RenderedDocument) {
36
36
. join ( "tests/refs" )
37
37
. join ( name) ;
38
38
39
+ let diffs_path = PathBuf :: from ( env ! ( "CARGO_MANIFEST_DIR" ) )
40
+ . join ( "tests/diffs" )
41
+ . join ( name) ;
42
+
39
43
std:: fs:: create_dir_all ( & refs_path) . unwrap ( ) ;
40
44
41
45
if document. is_empty ( ) {
@@ -46,33 +50,14 @@ pub fn save_refs(name: &str, renderer: &Renderer, document: RenderedDocument) {
46
50
let reference = load_from_memory ( & std:: fs:: read ( & ref_path) . unwrap ( ) ) . unwrap ( ) . into_rgba8 ( ) ;
47
51
let actual = load_from_memory ( & document[ 0 ] ) . unwrap ( ) . into_rgba8 ( ) ;
48
52
49
- let width = max ( reference. width ( ) , actual. width ( ) ) ;
50
- let height = max ( reference. height ( ) , actual. height ( ) ) ;
51
-
52
- let mut pixel_diff = 0 ;
53
-
54
- for x in 0 ..width {
55
- for y in 0 ..height {
56
- let actual_pixel = actual. get_pixel_checked ( x, y) ;
57
- let expected_pixel = reference. get_pixel_checked ( x, y) ;
53
+ let ( diff_image, pixel_diff) = get_diff ( & reference, & actual) ;
58
54
59
-
60
-
61
- match ( actual_pixel, expected_pixel) {
62
- ( Some ( actual) , Some ( expected) ) => {
63
- if is_pix_diff ( expected, actual) {
64
- pixel_diff += 1 ;
65
- }
66
- }
67
- ( Some ( _) , None ) => {
68
- pixel_diff += 1 ;
69
- }
70
- ( None , Some ( _) ) => {
71
- pixel_diff += 1 ;
72
- }
73
- _ => unreachable ! ( ) ,
74
- }
75
- }
55
+ if pixel_diff != 0 {
56
+ std:: fs:: create_dir_all ( & diffs_path) . unwrap ( ) ;
57
+ let diff_path = diffs_path. join ( format ! ( "{}.png" , renderer. name( ) ) ) ;
58
+ diff_image
59
+ . save_with_format ( & diff_path, image:: ImageFormat :: Png )
60
+ . unwrap ( ) ;
76
61
}
77
62
78
63
assert_eq ! ( pixel_diff, 0 ) ;
@@ -87,6 +72,51 @@ pub fn save_refs(name: &str, renderer: &Renderer, document: RenderedDocument) {
87
72
}
88
73
}
89
74
75
+ pub fn get_diff (
76
+ expected_image : & RgbaImage ,
77
+ actual_image : & RgbaImage ,
78
+ ) -> ( RgbaImage , i32 ) {
79
+ let width = max ( expected_image. width ( ) , actual_image. width ( ) ) ;
80
+ let height = max ( expected_image. height ( ) , actual_image. height ( ) ) ;
81
+
82
+ let mut diff_image = RgbaImage :: new ( width * 3 , height) ;
83
+
84
+ let mut pixel_diff = 0 ;
85
+
86
+ for x in 0 ..width {
87
+ for y in 0 ..height {
88
+ let actual_pixel = actual_image. get_pixel_checked ( x, y) ;
89
+ let expected_pixel = expected_image. get_pixel_checked ( x, y) ;
90
+
91
+ match ( actual_pixel, expected_pixel) {
92
+ ( Some ( actual) , Some ( expected) ) => {
93
+ diff_image. put_pixel ( x, y, * expected) ;
94
+ diff_image. put_pixel ( x + 2 * width, y, * actual) ;
95
+ if is_pix_diff ( expected, actual) {
96
+ pixel_diff += 1 ;
97
+ diff_image. put_pixel ( x + width, y, Rgba ( [ 255 , 0 , 0 , 255 ] ) ) ;
98
+ } else {
99
+ diff_image. put_pixel ( x + width, y, Rgba ( [ 0 , 0 , 0 , 255 ] ) )
100
+ }
101
+ }
102
+ ( Some ( actual) , None ) => {
103
+ pixel_diff += 1 ;
104
+ diff_image. put_pixel ( x + 2 * width, y, * actual) ;
105
+ diff_image. put_pixel ( x + width, y, Rgba ( [ 255 , 0 , 0 , 255 ] ) ) ;
106
+ }
107
+ ( None , Some ( expected) ) => {
108
+ pixel_diff += 1 ;
109
+ diff_image. put_pixel ( x, y, * expected) ;
110
+ diff_image. put_pixel ( x + width, y, Rgba ( [ 255 , 0 , 0 , 255 ] ) ) ;
111
+ }
112
+ _ => unreachable ! ( ) ,
113
+ }
114
+ }
115
+ }
116
+
117
+ ( diff_image, pixel_diff)
118
+ }
119
+
90
120
fn is_pix_diff ( pixel1 : & Rgba < u8 > , pixel2 : & Rgba < u8 > ) -> bool {
91
121
if pixel1. 0 [ 3 ] == 0 && pixel2. 0 [ 3 ] == 0 {
92
122
return false ;
0 commit comments